Java计算不同时区ZonedDateTime间隔时Duration.toHours返回0
问题原因分析
核心逻辑原因
Duration.between计算的是两个时间点对应的物理瞬时时间差,计算时会自动将ZonedDateTime转换为UTC对应的Instant值再做差值计算,不会参考时区的显示时间。- 你两次调用
ZonedDateTime.now()的间隔只有不到2毫秒,两个时间对应的UTC瞬时值差异仅为1.496毫秒左右:- 加尔各答时区时间
2021-11-10T16:44:38.237844+05:30转换为UTC时间为2021-11-10T11:14:38.237844Z - 多伦多时区时间
2021-11-10T06:14:38.239340-05:00转换为UTC时间为2021-11-10T11:14:38.239340Z
- 加尔各答时区时间
- 两者的时间差仅1.496毫秒,远小于1小时,调用
toHours()方法时会取整数部分,因此返回结果为0,符合方法设计逻辑。
常见认知误区
预期得到非零结果,大概率是混淆了「两个时间点的物理时间差」和「两个时区的法定偏移差」:如果需要计算两个时区的固定偏移差,不要通过两次调用now()的方式计算,应该直接获取时区规则计算偏移差值,示例逻辑如下:
ZoneId calcuttaZone = ZoneId.of("Asia/Calcutta"); ZoneId torontoZone = ZoneId.of("America/Toronto"); // 取同一个瞬时点计算两个时区的偏移,避免调用now()的时间差影响结果 Instant anchor = Instant.now(); ZoneOffset calcuttaOffset = calcuttaZone.getRules().getOffset(anchor); ZoneOffset torontoOffset = torontoZone.getRules().getOffset(anchor); Duration offsetDiff = Duration.ofSeconds(calcuttaOffset.getTotalSeconds() - torontoOffset.getTotalSeconds()); System.out.println(offsetDiff.toHours()); // 输出对应时区偏移的小时差
内容的提问来源于stack exchange,提问作者We work better
相关产品推荐
相关产品推荐

