2017-06-05 34 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