In this quick tutorial, we're going to take a look at two new classes for working with dates introduced in Java 8: Period and Duration.
Both classes can be used to represent an amount of time or determine the difference between two dates. The main distinction between the two classes is that Period uses date-based values, while Duration uses time-based values.
2. Period Class
The Period class uses the units year, month and day to represent a period of time.
We can obtain a Period object as the difference between two dates by using the between() method:
LocalDate startDate = LocalDate.of(2015, 2, 20); LocalDate endDate = LocalDate.of(2017, 1, 15); Period period = Period.between(startDate, endDate);
Then, we can determine the date units of the period using the methods getYears(), getMonths(), getDays():
LOG.info("Years:" + period.getYears() + " months:" + period.getMonths() + " days:"+period.getDays());
In this case, the isNegative() method, which returns true if any of the units are negative, can be used to determine if the endDate is higher than the startDate:
If isNegative() returns false, then the startDate is earlier than the endDate value.
Another way to create a Period object is based on the number of days, months, weeks or years using dedicated methods:
Period fromUnits = Period.of(3, 10, 10); Period fromDays = Period.ofDays(50); Period fromMonths = Period.ofMonths(5); Period fromYears = Period.ofYears(10); Period fromWeeks = Period.ofWeeks(40); assertEquals(280, fromWeeks.getDays());
If only one of the values is present, for example by using the ofDays() method, then the value of the other units is 0.
In the case of the ofWeeks() method, the parameter value is used to set the number of days by multiplying it by 7.
We can also create a Period object by parsing a text sequence, which has to have the format “PnYnMnD”:
Period fromCharYears = Period.parse("P2Y"); assertEquals(2, fromCharYears.getYears()); Period fromCharUnits = Period.parse("P2Y3M5D"); assertEquals(5, fromCharUnits.getDays());
The value of the period can be increased or decreased by using methods of the form plusX() and minusX(), where X represents the date unit:
assertEquals(56, period.plusDays(50).getDays()); assertEquals(9, period.minusMonths(2).getMonths());
3. Duration Class
The Duration class represents an interval of time in seconds or nanoseconds and is most suited for handling shorter amounts of time, in cases that require more precision.
We can determine the difference between two instants as a Duration object using the between() method:
Instant start = Instant.parse("2017-10-03T10:15:30.00Z"); Instant end = Instant.parse("2017-10-03T10:16:30.00Z"); Duration duration = Duration.between(start, end);
Then we can use the getSeconds() or getNanoseconds() methods to determine the value of the time units:
Alternatively, we can obtain a Duration instance from two LocalDateTime instances:
LocalTime start = LocalTime.of(1, 20, 25, 1024); LocalTime end = LocalTime.of(3, 22, 27, 1544); Duration.between(start, end).getSeconds();
The isNegative() method can be used to verify if the end instant is higher than the start instant:
We can also obtain a Duration object based on several time units, using the methods ofDays(), ofHours(), ofMillis(), ofMinutes(), ofNanos(), ofSeconds():
Duration fromDays = Duration.ofDays(1); assertEquals(86400, fromDays.getSeconds()); Duration fromMinutes = Duration.ofMinutes(60);
To create a Duration object based on a text sequence, this has to be of the form “PnDTnHnMn.nS”:
Duration fromChar1 = Duration.parse("P1DT1H10M10.5S"); Duration fromChar2 = Duration.parse("PT10M");
A duration can be converted to other time units using toDays(), toHours(), toMillis(), toMinutes():
A duration value can be increased or decreased by using methods of the form plusX() or minusX(), where X can stand for days, hours, millis, minutes, nanos or seconds:
assertEquals(120, duration.plusSeconds(60).getSeconds()); assertEquals(30, duration.minusSeconds(30).getSeconds());
We can also use the plus() and minus() methods with a parameter that specifies the TemporalUnit to add or subtract:
assertEquals(120, duration.plus(60, ChronoUnit.SECONDS).getSeconds()); assertEquals(30, duration.minus(30, ChronoUnit.SECONDS).getSeconds());
In this tutorial, we've shown how we can use the Period and Duration classes.
As always, the full source code of the examples can be found over on GitHub.