Duration.toHours returns 零

Duration.toHours returns zero

在下面的输出部分中,显示的“中间小时数”为零。预期的结果是一个非零值。

Java代码:

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());

输出:

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

它为零,因为您实际上是在比较“现在”和“现在”。这些 ZonedDateTime 对象位于不同区域的事实无关紧要,因为它们具有时区意识 - 它们指向同一时刻。

如果你想比较每个时区本地时间之间的小时数,你可以通过将它们转换为LocalDateTime对象来做到这一点:

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

...这会给你 -10。

对现有答案的适度补充。

首先,您不需要忍受两次调用 now() 之间不确定的时间间隔。仅调用 now() 一次并将结果用于两个 ZonedDateTime 对象。从另一个推导出一个:

    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);

现在输出:

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

不仅秒,连毫秒都一致

看来你真正找到的是两个时间之间当前 UTC 偏移量的差异。现有的答案在这一点上很好。我提出了一个替代方案,我认为它更直接地表达了我们想要偏移量之间的差异。我并不是说一种解决方案总体上优于另一种解决方案。

    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

前一行说时差是 10 小时 30 分钟。转换为小时时,只包括整小时,所以 10.