Duration.toHours returns zero

Viewed 100

In the output section below, the "Hours in-between" displayed is zero. The result expected is a non-zero value.

The Java code:

ZonedDateTime zdt1 = ZonedDateTime.now(ZoneId.of("Asia/Calcutta"));
ZonedDateTime zdt2 = ZonedDateTime.now(ZoneId.of("America/Toronto"));
Duration duration2 = Duration.between(zdt1, zdt2);

System.out.format("ZonedDateTime 1 %s\n", zdt1);
System.out.format("ZonedDateTime 2 %s\n", zdt2);
System.out.format("Hours in between %d\n", duration2.toHours());

The output:

ZonedDateTime 1 2021-11-10T16:44:38.237844+05:30[Asia/Calcutta]
ZonedDateTime 2 2021-11-10T06:14:38.239340-05:00[America/Toronto]
Hours in between 0
2 Answers

It's zero because you're literally comparing "now" with "now". The fact that those ZonedDateTime objects are in different zones is irrelevant, since they're timezone aware - they point to the same instant in time.

If you want to compare the number of hours between the local time in each timezone, you can do that by converting them to LocalDateTime objects:

Duration duration2 = Duration.between(zdt1.toLocalDateTime(), zdt2.toLocalDateTime());

...which will give you -10.

A modest supplement to the existing answer.

First, you don’t need to live with an uncertain amount of time elapsing between your two calls to now(). Call now() only once and use the result for both ZonedDateTime objects. Derive one from the other:

    ZonedDateTime zdt1 = ZonedDateTime.now(ZoneId.of("Asia/Calcutta"));
    ZonedDateTime zdt2 = zdt1.withZoneSameInstant(ZoneId.of("America/Toronto"));

    System.out.format("ZonedDateTime 1 %s%n", zdt1);
    System.out.format("ZonedDateTime 2 %s%n", zdt2);

Output right now:

ZonedDateTime 1 2021-11-11T05:31:02.380+05:30[Asia/Calcutta]
ZonedDateTime 2 2021-11-10T19:01:02.380-05:00[America/Toronto]

Not only the seconds, even the milliseconds agree.

It seems that what you are really finding the difference in the current UTC offset between the two times. The existing answer is fine on this point. I am presenting an alternative that I think more directly expresses that we want the difference between the offsets. I am not saying that one solution is overall better than the other.

    int diffSeconds = zdt1.getOffset().getTotalSeconds() - zdt2.getOffset().getTotalSeconds();
    Duration duration2 = Duration.ofSeconds(diffSeconds);

    System.out.format("Amount of time in between %s%n", duration2);
    System.out.format("Hours in between %d%n", duration2.toHours());
Amount of time in between PT10H30M
Hours in between 10

The former line says that the difference is 10 hours 30 minutes. When converting to hours, only the whole hours are included, so 10.

Related