Comparing Durations
The Duration class overrides the equals() method and the hashCode() method of the Object class, and implements the Comparable<Duration> interface. Durations can readily be used in collections. The code below illustrates comparing durations.
Duration eatBreakFast = Duration.ofMinutes(20L); // PT20M
Duration eatLunch = Duration.ofSeconds(30L*60); // PT30M
Duration eatSupper = Duration.of(45L, ChronoUnit.MINUTES); // PT45M
out.println(eatBreakFast.equals(eatLunch)); // false
out.println(Duration.ofSeconds(0).equals(Duration.ZERO)); // true
List<Duration> ld = Arrays.asList(eatSupper, eatBreakFast, eatLunch );
Collections.sort(ld); // Natural order.
out.println(ld); // [PT20M, PT30M, PT45M]
boolean equals(Object otherDuration)
Determines whether the total length of this duration is equal to the total length of the other duration.
int hashCode()
Returns a hash code for this duration.
int compareTo(Duration otherDuration)
Compares the total length of this duration to the total length of the other duration.
Creating Modified Copies of Durations
The Duration class provides withUNIT() methods to set a new value for each time unit individually, while the value of the other time unit is retained. Note that each method call returns a new Duration object, and chaining method calls works as expected.
Duration oneDuration = Duration.ZERO // PT0S
.withNanos(500_000_000) // New copy: PT0.5S
.withSeconds(12L*60*60); // New copy: PT12H0.5S
Duration withNanos(int nanoOfSecond)
Duration withSeconds(long seconds)
Return a copy of this duration where either the nanosecond or the seconds are set to the value of the argument, respectively. The value of the other time unit is retained.
Temporal Arithmetic with Durations
The Duration class provides plus and minus methods that return a copy of the original object that has been incremented or decremented by a specific amount specified in terms of a unit—for example, as a number of days, hours, minutes, or seconds.
Duration max20H = Duration.ZERO // PT0S
.plusHours(10) // PT10H
.plusMinutes(10*60 + 30) // PT20H30M
.plusSeconds(6*60*60 + 15) // PT26H30M15S
.minusMinutes(2*60 + 30) // PT24H15S
.minusSeconds(15); // PT24H
The plus() and the minus() methods also allow the amount to be qualified by a unit that has a standard or an estimated duration, as illustrated by the statement below, which is equivalent to the one above.
Duration max20H2 =
Duration.ZERO // PT0S
.plus(10L, ChronoUnit.HOURS) // PT10H
.plus(10*60 + 30, ChronoUnit.MINUTES) // PT20H30M
.plus(6*60*60L + 15, ChronoUnit.SECONDS) // PT26H3015S
.minus(2*60 + 30, ChronoUnit.MINUTES) // PT24H15S
.minus(15, ChronoUnit.SECONDS); // PT24H
The code below shows the plus() and the minus() methods of the Duration class that take a Duration as the amount to add or subtract.
Duration eatBreakFast = Duration.ofMinutes(20L); // PT20M
Duration eatLunch = Duration.ofSeconds(30L*60); // PT30M
Duration eatSupper = Duration.of(45L, ChronoUnit.MINUTES); // PT45M
Duration totalTimeForMeals = eatBreakFast // PT20M
.plus(eatLunch) // PT50M
.plus(eatSupper); // PT1H35M
The statement below shows other arithmetic operations on durations and how they are carried out, together with what would be printed if the intermediate results were also written out.
Duration result = Duration.ofSeconds(-100, -500_000_000) // -100.5 => PT-1M-40.5S
.abs() // abs(-100.5) = 100.5 => PT1M40.5S
.multipliedBy(4) // 100.5*4 = 402 => PT6M42S
.dividedBy(2); // 402 / 2 = 201 => PT3M21S
Duration plusDays/minusDays(long days)
Duration plusHours/minusHours(long hours)
Duration plusMinutes/minusMinutes(long minutes)
Duration plusSeconds/minusSeconds(long seconds)
Duration plusMillis/minusMillis(long millis)
Duration plusNanos/minusNanos(long nanos)
Return a copy of this duration, with the specified value of the unit designated by the method name added or subtracted, but converted first to seconds, if necessary. Note that the argument type is long.
Duration plus(long amountToAdd, TemporalUnit unit)
Duration minus(long amountToSub, TemporalUnit unit)
Return a copy of this duration with the specified amount added or subtracted, respectively, according to the TemporalUnit specified (p. 1044).
Valid ChronoUnit constants to qualify the amount specified in the method call are the following: NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, HALF_DAYS, and DAYS (p. 1044). These units have a standard or an estimated duration. Other units result in an UnsupportedTemporalTypeException.
Duration plus(Duration duration)
Duration minus(Duration duration)
Return a copy of this duration, with the specified duration added or subtracted.
Duration abs()
Returns a copy of this duration with a positive length.
Duration negated()
Returns a copy of this duration where the length has been negated.
Duration dividedBy(long divisor)
Duration multipliedBy(long multiplicand)
The first method returns a new instance with the result of dividing the length of this duration by the specified divisor. Division by zero would bring down untold calamities.
The second method returns a new instance with the result of multiplying the length of this duration by the specified multiplicand.
We can perform arithmetic operations on durations and temporal objects. The following code uses the plus() and minus() methods of the LocalTime and LocalDateTime classes that take a TemporalAmount as an argument (p. 1040). We can add and subtract durations from LocalTime and LocalDateTime objects, but not from LocalDate objects, as a LocalDate object only supports date units.
LocalTime timeA = LocalTime.of(14,45,30); // 14:45:30
LocalDate dateA = LocalDate.of(2021, 4, 28); // 2021-04-28
LocalDateTime dateTimeA = LocalDateTime.of(dateA, timeA); // 2021-04-28T14:45:30
Duration amount = Duration.ofMinutes(20); // PT20M
timeA = timeA.plus(amount); // 15:05:30
dateTimeA = dateTimeA.minus(amount); // 2021-04-28T14:25:30
dateA = dateA.minus(amount); // UnsupportedTemporalTypeException
Example 17.7 illustrates implementing duration-based loops. The program prints the showtimes, given when the first show starts, the duration of the show, and when the theatre closes. The for(;;) loop at (1) uses the LocalTime.isBefore() method and the LocalTime.plus(duration) method to calculate the showtimes.
Example 17.7 Duration-Based Loop
import java.time.LocalTime;
import java.time.Duration;
public class DurationBasedLoop {
public static void main(String[] args) {
Duration duration = Duration.ofHours(2).plusMinutes(15); // PT2H15M
LocalTime firstShowTime = LocalTime.of(10, 10); // 10:10
LocalTime endTimeExclusive = LocalTime.of(23, 0); // 23:00
for (LocalTime time = firstShowTime; // (1)
time.plus(duration).isBefore(endTimeExclusive);
time = time.plus(duration)) {
System.out.println(“Showtime (” + duration + “): ” + time);
}
System.out.println(“Closing time: ” + endTimeExclusive);
}
}
Output from the program:
Showtime (PT2H15M): 10:10
Showtime (PT2H15M): 12:25
Showtime (PT2H15M): 14:40
Showtime (PT2H15M): 16:55
Showtime (PT2H15M): 19:10
Closing time: 23:00