2016-07-29 307 views
1

使用Spring MVC(春季啓動),我可以從傑克遜:解析ZonedDateTime與時區ID

2016-07-26T05:30:47+01:00 

但無法反序列化ZonedDateTime

2016-07-26T05:30:47+01:00 Europe/Paris 

我如何能明確地添加時區,並仍然能夠反序列化它?

+0

術語「歐洲/巴黎」表示包括任何轉換歷史記錄,實際和未來夏令時規則以及底層時區數據版本的完整時區。所以序列化和反序列化可能需要傳輸所有這些東西,不僅是字符串「歐洲/巴黎」。在我看來,將所有序列化並不是一個好主意。您是否考慮過僅序列化ZonedDateTime的時刻以確保更好的性能? –

回答

0

您可以指定帶有可選部分(由[]分隔)的模式,以指示某個字段是可選的,並使用@JsonFormat註釋將其添加到相應的字段。

例如,藉此類:

public class OptionalTimeZoneTest { 

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX[ VV]") 
    private ZonedDateTime date; 

    // getter and setter 
} 

注意的最後部分([ VV]):內[]圖案是一個可選的部分,所以解析器嘗試來分析它,如果存在的話。和模式VV是區域ID(或時區的名稱;更多詳細信息,請看看javadoc

有了這個,這兩種格式可以讀取:

ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(new JavaTimeModule()); 
// add this to preserve the same offset (don't convert to UTC) 
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); 

// without timezone 
String json = "{ \"date\": \"2016-07-26T05:30:47+01:00\" }"; 
OptionalTimeZoneTest value = mapper.readValue(json, OptionalTimeZoneTest.class); 
System.out.println(value.getDate()); // 2016-07-26T05:30:47+01:00 

// with timezone 
json = "{ \"date\": \"2016-07-26T05:30:47+01:00 Europe/Paris\" }"; 
value = mapper.readValue(json, OptionalTimeZoneTest.class); 
System.out.println(value.getDate()); // 2016-07-26T05:30:47+02:00[Europe/Paris] 

輸出是:

2016-07-26T05:30:47 + 01:00
2016-07-26T05:30:47 + 02:00 [歐洲/巴黎]

請注意,在第一種情況下,輸出爲2016-07-26T05:30:47+01:00(因爲它沒有時區,所以應用了+01:00偏移量)。

但在第二種情況下,輸出爲2016-07-26T05:30:47+02:00[Europe/Paris],因爲在Europe/Paris時區26/07/2016 is summer-time(所以偏移量爲+02:00)。而java.time API的實現方式是在分析此類String時,時區優先。


如果希望所有ZonedDateTime實例轉換爲UTC,您可以刪除此行:

mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); 

沒有它,日期將被轉換爲UTC,輸出將是:

2016-07-26T04:30:47Z [UTC]
2016-07-26T03:30:47Z [UTC]