杰克逊:用时区id解析ZonedDateTime

时间:2016-07-29 09:14:49

标签: java spring-mvc spring-boot jackson java-time

使用Spring MVC(Spring启动),我可以从

反序列化ZonedDateTime
2016-07-26T05:30:47+01:00

但不是来自

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

如何明确添加时区并仍能反序列化?

1 个答案:

答案 0 :(得分:3)

您可以指定带有可选部分的模式(由[]分隔),以指示某些字段是可选的,并使用@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]