java - 为什么在评估 ZoneInfo 部分时 GregorianCalendar 和 OffsetDateTime 之间的转换失败?

标签 java gregorian-calendar

我正在将 OffsetDateTime 转换为 GregorianCalendar,作为出站 Web 服务填充值的一部分。我只是想测试一下实际的转换。

它失败了,我不明白为什么 - 这是测试方法:

@Test
public void testOffsetDateTimeToGregorianCalendar() {
    // given the current gregorian utc time
    GregorianCalendar expectedGregorianUtcNow = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
    OffsetDateTime expectedUtcOffsetDateTime = OffsetDateTime.from(expectedGregorianUtcNow.toZonedDateTime());

    // when converting to a GregorianCalendar
    GregorianCalendar actualGregorianUtcNow = GregorianCalendar.from(expectedUtcOffsetDateTime.toZonedDateTime());

    // then make sure we got the correct value
    assertThat(actualGregorianUtcNow, equalTo(expectedGregorianUtcNow));
}

在 equalto 中,比较在计算 gregorianCutover 时失败。为什么?这是一个错误吗?

看起来实际有: 格里高利切换 = -9223372036854775808 预计有: 格里高利安切换 = -12219292800000

其他一切都是正确的,如单元测试输出中所示(gregorianCutover 没有出现在那里):

    java.lang.AssertionError: 
    Expected:<java.util.GregorianCalendar[time=1458667828375,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2016,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=4,DAY_OF_MONTH=22,DAY_OF_YEAR=82,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=30,SECOND=28,MILLISECOND=375,ZONE_OFFSET=0,DST_OFFSET=0]>
    but: was <java.util.GregorianCalendar[time=1458667828375,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2016,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=4,DAY_OF_MONTH=22,DAY_OF_YEAR=82,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=30,SECOND=28,MILLISECOND=375,ZONE_OFFSET=0,DST_OFFSET=0]>

我做错了什么吗?

最佳答案

基本上,据我所知,java.time 不会尝试对公历转换进行建模 - 因此当 OffsetDateTime 转换回 GregorianCalendar,这是通过将其建模为具有在时间开始时切换回的公历来完成的。因此,GregorianCalendar.from(ZoneDateTime) 的文档:

Since ZonedDateTime does not support a Julian-Gregorian cutover date and uses ISO calendar system, the return GregorianCalendar is a pure Gregorian calendar and uses ISO 8601 standard for week definitions, which has MONDAY as the FirstDayOfWeek and 4 as the value of the MinimalDaysInFirstWeek.

理想情况下,我建议您避免在日期/时间 API 方面使用 java.util.*...在任何地方都坚持使用 java.time。但如果你真的需要,我可能建议不要使用 GregorianCalendar.equals 来测试相等性 - 分别检查即时时间和时区,如果这些是你感兴趣的东西.

关于java - 为什么在评估 ZoneInfo 部分时 GregorianCalendar 和 OffsetDateTime 之间的转换失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36161596/

相关文章:

java - 无法使用带有 java 的 selenium webdriver 从页面上存在的总共 6 个相似元素中找到特定按钮

java - 通过同时点击不同的按钮来播放和停止声音

java - Lombok @NonNull 与 Validate.notNull

java - 当我返回 Activity 时,如何重新启动 BarcodeDetector 以获得新结果?

java - Java 中的运算符重载(整数包装类)?

java - Android:公历问题

java - 将天数组织成年、月、日、小时的单独部分。 java

java - 在 Java 公历中设置区域设置

database - 回历日期插入数据库

Java 公历格式