Learn to compare two instances of ZonedDateTime
either in the same timezone or in different timezones in Java 8.
2. Comparing at Same Instant
As we know an instance of ZonedDateTime is a point in the universal timeline with an offset. So to compare two such instances, logically, both instances should be in the same time zone first, and then we should compare the date and time values.
Exactly this happens when we use the following methods to compare two ZonedDateTime instances.
- isAfter()
- isBefore()
- isEqual()
The zdt1.isAfter(zdt2)
compares the instant of both date-time values and it is similar to zdt1.toInstant().equals(zdt2.toInstant())
.
These methods do not use the field by field comparison and compare the epoch seconds from both instances,
ZonedDateTime zdtNow = ZonedDateTime.now();
System.out.println("Time in IST" + zdtNow);
ZonedDateTime zdtNowinUTC = zdtNow.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println("Time in UTC" + zdtNowinUTC);
if(zdtNow.toEpochSecond() == zdtNowinUTC.toEpochSecond()) { //true
System.out.println("Epoch Seconds are equal");
}
System.out.println(zdtNow.isEqual(zdtNowinUTC)); //true
System.out.println(zdtNow.isBefore(zdtNowinUTC)); //false
System.out.println(zdtNow.isAfter(zdtNowinUTC)); //false
Program output.
2022-02-16T00:17:34.656584400+05:30[Asia/Calcutta]
2022-02-15T18:47:34.656584400Z[UTC]
Epoch Seconds are equal
true
false
false
2. Field by Field Comparison
If we have two ZonedDateTime instances and we want to make a field b field comparison then we can use the following methods:
- compareTo()
- equals()
Both methods compare the instances, including the chronology. The comparison is based first on the instant, then on the local date-time, then on the zone ID, then on the chronology. So compareTo() compares all 4 information in both instances.
It returns a value negative
if less, positive
if greater and 0 if both date-time instances are equal.
ZonedDateTime zdtNow = ZonedDateTime.now(); System.out.println("Time in IST" + zdtNow); ZonedDateTime zdtNowinUTC = zdtNow.withZoneSameInstant(ZoneId.of("UTC")); System.out.println("Time in UTC" + zdtNowinUTC); System.out.println(zdtNow.compareTo(zdtNowinUTC)); System.out.println(zdtNow.equals(zdtNowinUTC));
Program output.
1 false
3. Comparing ZonedDateTime During DST Changes
We should remember that ZonedDateTime is date-time value with a zone id and offset information in the ISO-8601 calendar system. Note that a zone id can have different offset values during the year, mostly during the DST (Daylight Saving Time) changes when the offset value increases or decreases by 1 hour.
For most timezones that do not use the DST, and non-overlapping or non-gap time in DST affected time zones, the isEqual(), isBefore() or isAfter() methods gives consistent and predictable results.
Our only concern is during the overlap (when clocks jump forward) and the gap (when clocks set back).
- For Gaps, the general strategy is to move the instance in the later offset.
- For Overlaps, the previous offset will be retained if available. In case the previous offset is not available or invalid, two additional methods
withEarlierOffsetAtOverlap()
andwithLaterOffsetAtOverlap()
have been provided.
In the given example, the two instances are given. One instance is in the overlap period and the other is after the overlap period. Notice the offset value printed in the first two print statements.
During the overlap, the previous offset (-05:00) has been retained. We used withLaterOffsetAtOverlap() method to use the most later offset value i.e. -06:00.
ZonedDateTime zonedDTDuringOverlap = ZonedDateTime
.of(LocalDateTime.of(2021, 11, 07, 1, 05, 53), ZoneId.of("US/Central"));
ZonedDateTime zonedDTAfterOverlap = ZonedDateTime
.of(LocalDateTime.of(2021, 11, 07, 2, 05, 53), ZoneId.of("US/Central"));
System.out.println("During overlap: " + zonedDTDuringOverlap);
System.out.println("After overlap(): " + zonedDTAfterOverlap);
ZonedDateTime zonedDT = zonedDTDuringOverlap.withLaterOffsetAtOverlap();
System.out.println("Using withLaterOffsetAtOverlap(): " + zonedDT);
Program Output.
During overlap: 2021-11-07T01:05:53-05:00[US/Central]
After overlap(): 2021-11-07T02:05:53-06:00[US/Central]
Using withLaterOffsetAtOverlap(): 2021-11-07T01:05:53-06:00[US/Central]
Happy Learning !!