2016-07-29 80 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]