2017-06-05 38 views
2

鉴于以下单元测试:ZonedDateTime通过杰克逊往返产生不平等ZonedDateTime

@Test 
public void zonedDateTimeCorrectlyRestoresItself() { 

    // construct a new instance of ZonedDateTime 
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Z")); 
    // offset = {[email protected]} "Z" 
    // zone = {[email protected]} "Z" 

    String converted = now.toString(); 

    // restore an instance of ZonedDateTime from String 
    ZonedDateTime restored = ZonedDateTime.parse(converted); 
    // offset = {[email protected]} "Z" 
    // zone = {[email protected]} "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 = {[email protected]} "Z" 
    // zone = {[email protected]} "Z" 


    String converted = objectMapper.writeValueAsString(now); 

    // restore an instance of ZonedDateTime from String 
    ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class); 
    // offset = {[email protected]} "Z" 
    // zone = {[email protected]} "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 = {[email protected]} "Z" 
    // zone = {[email protected]} "Z" 

    String converted = objectMapper.writeValueAsString(now); 

    // restore an instance of ZonedDateTime from String 
    ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class); 
    // offset = {[email protected]} "Z" 
    // zone = {[email protected]} "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()?就我个人而言,我认为这是杰克逊的一个缺陷,但我还没有足够的信心在没有反馈的情况下为它开启一个问题。

回答

5

引述维基百科ISO 8601

如果时间是UTC,没有空格的时间后直接添加ZZ是零UTC抵消的区域指示符。因此"09:30 UTC"表示为"09:30Z""0930Z""14:45:15 UTC"将是"14:45:15Z""144515Z"

UTC时间也被称为祖鲁时间,因为祖鲁族是Z.

北约拼音字母词

Z不是一个区。 UTC是区域,然后代表使用格式化的字符串中的Z

千万不要使用ZoneId.of("Z")。这是不对的。

+2

'ZoneId.of(“Z”)'不会比根据[文档]错误(https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html它应该工作:“如果区域ID等于'Z',结果是'ZoneOffset.UTC'。 “ –

+0

@ OleV.V。我最初使用文档来查找“Z”的ZoneId,这就是我首先使用它的原因。现在我已经用“UTC”替换了所有“Z”的实例,但没有看到杰克逊代码实例的ZonedDateTime对象,很难说它是否是一个错误。 – anon58192932