Comparing Two ZonedDateTime Instances

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() and  withLaterOffsetAtOverlap() 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 !!

Sourcecode on Github

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.