考虑到以下单元测试:
@Test
public void zonedDateTimeCorrectlyRestoresItself() {
// construct a new instance of ZonedDateTime
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Z"));
// offset = {ZoneOffset@3820} "Z"
// zone = {ZoneOffset@3820} "Z"
String converted = now.toString();
// restore an instance of ZonedDateTime from String
ZonedDateTime restored = ZonedDateTime.parse(converted);
// offset = {ZoneOffset@3820} "Z"
// zone = {ZoneOffset@3820} "Z"
assertThat(now).isEqualTo(restored); // ALWAYS succeeds
}
@Test
public void jacksonIncorrectlyRestoresZonedDateTime() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.findAndRegisterModules();
objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
// construct a new instance of ZonedDateTime
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Z"));
// offset = {ZoneOffset@3820} "Z"
// zone = {ZoneOffset@3820} "Z"
String converted = objectMapper.writeValueAsString(now);
// restore an instance of ZonedDateTime from String
ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class);
// offset = {ZoneOffset@3820} "Z"
// zone = {ZoneOffset@3821} "UTC"
assertThat(now).isEqualTo(restored); // NEVER succeeds
}而这个解决办法是:
@Test
public void usingDifferentComparisonStrategySucceeds() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.findAndRegisterModules();
objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
// construct a new instance of ZonedDateTime
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Z"));
// offset = {ZoneOffset@3820} "Z"
// zone = {ZoneOffset@3820} "Z"
String converted = objectMapper.writeValueAsString(now);
// restore an instance of ZonedDateTime from String
ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class);
// offset = {ZoneOffset@3820} "Z"
// zone = {ZoneOffset@3821} "UTC"
// the comparison succeeds when a different comparison strategy is used
// checks whether the instants in time are equal, not the java objects
assertThat(now.isEqual(restored)).isTrue();
}我想我是想弄清楚为什么杰克逊内部不打电话给ZonedDateTime.parse()?就我个人而言,我认为这是杰克逊的一个缺陷,但我没有足够的信心来为它打开一个问题,只是没有一些反馈。
发布于 2017-06-05 15:45:13
引用维基百科的ISO 8601
如果时间为UTC,则在没有空格的时间之后直接添加一个
Z。Z是零UTC偏移量的区域指示符。因此,"09:30 UTC"被表示为"09:30Z"或"0930Z"。"14:45:15 UTC"将是"14:45:15Z"或"144515Z"。 UTC时间也被称为祖鲁时间,因为祖鲁是北约字母Z的拼音词。
Z不是一个区域。UTC是区域,然后使用格式化字符串中的Z表示该区域。
永远不要使用ZoneId.of("Z")。这是错误的。
https://stackoverflow.com/questions/44372498
复制相似问题