为什么在评估 ZoneInfo 部分时 GregorianCalendar 和 OffsetDateTime 之间的转换失败?
Why does conversion between GregorianCalendar and OffsetDateTime fail when evaluating the ZoneInfo part?
我正在将 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
并且预期有:
gregorianCutover = -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
.
理想情况下,我建议您避免在 date/time API 方面使用 java.util.*
...坚持使用 java.time
。但是,如果您确实需要,我可能建议您不要使用 GregorianCalendar.equals
来测试相等性 - 如果您对这些感兴趣,请分别检查时间和时区。
我正在将 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 并且预期有: gregorianCutover = -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 returnGregorianCalendar
is a pure Gregorian calendar and uses ISO 8601 standard for week definitions, which has MONDAY as theFirstDayOfWeek
and 4 as the value of theMinimalDaysInFirstWeek
.
理想情况下,我建议您避免在 date/time API 方面使用 java.util.*
...坚持使用 java.time
。但是,如果您确实需要,我可能建议您不要使用 GregorianCalendar.equals
来测试相等性 - 如果您对这些感兴趣,请分别检查时间和时区。