You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

跨EST/EDT时区比较Joda DateTime实例的相等性异常问题

问题根源:夏令时转换导致本地时间映射到同一UTC瞬间

这个问题的核心是美国纽约时区的夏令时结束规则,加上Joda DateTime的时间处理逻辑和equals()判定规则共同作用的结果。

1. Joda DateTime的equals()判定逻辑

Joda的DateTime.equals()方法只有在两个实例满足以下两个条件时才会返回true

  • 底层对应的UTC毫秒时间戳完全一致
  • 使用的**时区(Chronology)**完全相同

只要这两点符合,哪怕显示的本地时间字符串看起来不一样,equals()也会判定相等。

2. 纽约时区2018年11月4日的夏令时转换细节

美国东部时区(America/New_York)在2018年11月4日凌晨2:00会结束夏令时,时钟会回拨1小时到1:00。这会导致两个关键现象:

  • 本地时间2018-11-04T01:00:00会出现两次:一次是夏令时(UTC-4),一次是标准时间(UTC-5)
  • 本地时间2018-11-04T02:00:00不存在的——时钟从1:59:59夏令时直接跳到1:00:00标准时间,跳过了2:00这个时间点

3. 拆解你的两个DateTime实例

实例A的生成过程

DateTime A = new DateTime(2018, 11, 4, 1, 00, 0).plusHours(1);
  • 初始创建的2018-11-04T01:00:00是夏令时的1点(UTC-4),对应UTC时间2018-11-04T05:00:00Z
  • 加1小时后,触发夏令时转换,Joda自动调整时区,最终得到的UTC瞬间是2018-11-04T06:00:00Z,对应纽约标准时间的1:00(UTC-5),这就是A显示为2018-11-04T01:00:00.000-05:00的原因

实例B的生成过程

DateTime B = new DateTime(2018, 11, 4, 2, 00, 0);
  • 你试图创建一个不存在的本地时间,Joda的处理规则是将这个无效时间映射到下一个有效的UTC瞬间,也就是2018-11-04T06:00:00Z(和A的毫秒戳完全一致)。虽然显示字符串保留了你输入的02:00,但底层的实际时间瞬间已经和A对齐了。

4. 最终结论

A和B的UTC毫秒时间戳完全相同,且时区一致,所以equals()返回true。显示的本地时间不同只是Joda在处理无效时间时的字符串展示逻辑,不影响底层时间瞬间的判定。


内容的提问来源于stack exchange,提问作者Norcal

火山引擎 最新活动