比较 EST EDT 中的两个 joda DateTime 实例
Posted
技术标签:
【中文标题】比较 EST EDT 中的两个 joda DateTime 实例【英文标题】:Comparing two joda DateTime instances across EST EDT 【发布时间】:2018-08-30 20:45:26 【问题描述】:我有两个 DateTime
实例,A
和 B
,其中:
DateTime A = new DateTime(2018, 11, 4, 1, 00, 0).plusHours(1);
DateTime B = new DateTime(2018, 11, 4, 2, 00, 0);
println("A: "+ A +", "+ A.getChronology() +", ms "+ A.getMillis());
println("B: "+ B +", "+ B.getChronology() +", ms "+ B.getMillis());
println("A == B is "+ A.equals(B));
产生:
A: 2018-11-04T01:00:00.000-05:00, ISOChronology[America/New_York], ms 1541311200000
B: 2018-11-04T02:00:00.000-05:00, ISOChronology[America/New_York], ms 1541314800000
A == B is false
如何比较 A
和 B
以查看它们是否是同一个实例?
仔细看看A
和B
是如何实例化的。关键是A
和B
实际上指的是同一个时间点,即时钟从 EDT 调回纽约市的 EST。
【问题讨论】:
【参考方案1】:为了比较,您正确地使用了equals
。但它正在返回false
,因为它们不是同一时间点。如果您查看它们的值,您会发现A
实际上比B
早一小时:
A: 2018-11-04T01:00:00.000-05:00, ISOChronology[America/New_York], ms 1541311200000 B: 2018-11-04T02:00:00.000-05:00, ISOChronology[America/New_York], ms 1541314800000
getMillis()
的结果也不同,这意味着这些日期不是同一时间点。
这是因为new DateTime(2018, 11, 4, 1, 00, 0)
产生的日期/时间仍在美国东部时间 ("2018-11-04T01:00:00.000-04:00" ->凌晨 1 点在 -04:00 偏移)。
一小时后 (plusHours(1)
),您应该在偏移量 -04:00 处获得凌晨 2 点,但那是 DST ends in New York 的瞬间:时钟设置为 1 小时回到凌晨 1 点,并且偏移量变为 -05 :00 - 这就是为什么 A
是凌晨 1 点 -05:00。
另一方面,B
已经在美国东部标准时间(不再是夏令时),所以它设置为 -05:00 的凌晨 2 点。在A
之后一小时。
当 DST 结束时,我们有一个本地时间存在两次的奇怪情况(在这种情况下,1AM 和 1:59AM 之间的时间出现了两次:在 -04:00 偏移量,然后在 -05:00 偏移量) , Joda-Time 默认选择 DST 转换前的偏移量 (-04:00)。
不过,您可以使用withLaterOffsetAtOverlap()
覆盖它,这将在 DST 结束后采用偏移量。
// new DateTime creates 2018-11-04T01:00:00.000-04:00
DateTime A = new DateTime(2018, 11, 4, 1, 00, 0)
// adjust to offset after DST ends (2018-11-04T01:00:00.000-05:00)
.withLaterOffsetAtOverlap()
// add 1 hour
.plusHours(1);
DateTime B = new DateTime(2018, 11, 4, 2, 00, 0);
// now A and B are the same instant
System.out.println(A.equals(B)); // true
【讨论】:
我的问题是关于如何比较,而不是如何创建 DateTime 实例,因为我不创建这些实例。但事实上,无论您选择通过 EST 还是 EDT 来表示它们,它们都代表着相同的实际时刻。就像说 10/5 和 8/4 这两个比率不同,但它们确实评估为相同的数字,即 2。所以当我将 10/5 与 8/4 进行比较时,我可以使用 10/5 == 8 /4。声称它们不是同一个实例是错误的,因为当我转换为 UTC 时,两者都会给我完全相同的结果 @Norcal 如果getMillis()
返回不同的值,那么它们不是同一时刻 - 它们不对应于同一 UTC 时刻,只需调用 toInstant()
和你会发现 A 和 B 是不同的。我只是在解释,根据问题中的代码,为什么 A 和 B 不同。如果你仍然认为它们是一样的,那我也无能为力了。祝你好运
@Norcal 不管怎样,使用equals
是比较的正确方法,所以如果它返回false
,那么它们就不一样了。您的输出显示 A 是凌晨 1 点,B 是凌晨 2 点,所以我看不出它们如何相同。
也许您在 America/New_York 不是默认时区的某些环境中进行了测试 - 在这种情况下,A 和 B 将是相同的。但是当默认时区是 America/New_York 时,似乎是这种情况,那么你就有了我在回答中提到的 DST 效果(实际上,这就是我可以重现错误的方式 - 通过将我的默认时区设置为纽约,因为使用另一个,这不会发生)-我只是在猜测。如果您说它们相同,为什么问题中的输出显示 A 和 B 的值不同?
@Norcal 为了清楚起见,A 和 B 不一样,因为它们不会评估到相同的 UTC 时刻。 A
是 2018-11-04T01:00:00.000-05:00
,转换为 UTC(使用 A.toInstant()
)我得到 2018-11-04T06:00:00.000Z
,而 B
是 2018-11-04T02:00:00.000-05:00
并转换为 UTC(B.toInstant()
)得到 2018-11-04T07:00:00.000Z
。使用您在问题中提供的代码(并假设默认时区是 America/New_York,基于 getChronology()
的输出),A 比 B 早一小时,因此它们不相同。 【参考方案2】:
根据javadoc,你可以使用:
equals
:基于毫秒瞬间、年表和时区的平等
isEqual
: 这个瞬间是否等于传入的瞬间,仅以毫秒为单位进行比较
但是使用您示例中的日期,两种方法都返回false
。这是有道理的,主要是因为getMillis()
返回的值不同,所以日期实际上并不对应于同一 UTC 时刻,正如另一个答案所解释的那样。
【讨论】:
以上是关于比较 EST EDT 中的两个 joda DateTime 实例的主要内容,如果未能解决你的问题,请参考以下文章
在 R 中处理东部标准时间 (EST) 和东部夏令时 (EDT)
如何获取 pytz 时区的通用名称,例如。美国/纽约的 EST/EDT
如何使用纯函数可靠地将 POSIX 纪元秒转换为 EST/EDT 时间