使用不同的实例化方法时,OffsetDateTime对象的LocalDateTime和ZoneOffset值不同

问题描述

使用创建创建OffsetDateTime对象

  1. ofInstant(instant,zoneid)或通过
  2. 流畅的界面
如果通过流畅接口的实例化超过夏时制边界,则

可能导致不相等的对象(通过使用compareto断言或比较ZoneOffset和LocalDateTime字段)。考虑以下示例:

OffsetDateTime inAMonth = OffsetDateTime.Now().plusMonths(1);
OffsetDateTime inAMonth2 = OffsetDateTime.ofInstant(inAMonth.toInstant(),ZoneId.systemDefault());

10月中旬在中欧(ZoneId'Europe / Berlin'),由于plusMonths()重用了初始通话的offset({{1 }}。

有人知道为什么不重新计算偏移量吗?

我在单元测试中遇到了这个问题,我能想到的唯一解决方法是:a)不使用流畅的界面,或者b)在使用流畅的界面时避免使用跨DST跳转。不幸的是,不能使用OffsetDateTime以外的其他方式。

解决方法

有人知道为什么不重新计算偏移量吗?

由于OffsetDateTime返回的OffsetDateTime.now()值与任何特定时区都不相关,而仅与偏移量相关。偏移量被确定为“系统默认时区中的当前偏移量”,但此后与系统默认时区没有关联。

如果您想要与时区关联的 值,请改用ZonedDateTime.now()。之后,您可以将ZonedDateTime.now().plusMonths(1)的结果转换为OffsetDateTime

OffsetDateTime inAMonth = ZonedDateTime.now().plusMonths(1).toOffsetDateTime();
,

OffsetDateTime.plusMonth永远不会更改偏移量,因为它是OffsetDateTime-日期和时间,且具有恒定偏移量。如果您想更改偏移量,请使用ZonedDateTime,因为只有 zone的偏移量可以更改。

但是,使用瞬间和区域创建OffsetDateTime时,显然需要在指定的瞬间获取指定区域的偏移量。好吧,在指定时刻,已经发生了DST过渡,因此inAMonth2具有DST后的过渡偏移量。