Jackson / JavaTimeModule-处理不同的时区偏移量格式

Kev*_*vin 5 java jersey jackson datetime-parsing java-time

我正在调用一个API(使用Jersey),该API返回具有区域偏移量的Date Time。有时数据采用以下格式:

"2017-03-28T14:40:00+01:00"
Run Code Online (Sandbox Code Playgroud)

有时是这种格式(我对此无能为力)

"2017-03-28T14:40:00+0100"  (where the ':' in timezone offset is missing).
Run Code Online (Sandbox Code Playgroud)

我想将它们编组为java.time.ZonedDateTime对象。我JavaTimeModule()在泽西岛使用ObjectMapper

objectMapper.registerModule(new JavaTimeModule());
Run Code Online (Sandbox Code Playgroud)

问题:是否有任何方法可以使对象映射器足够灵活以处理in +01:00或in的时区偏移+0100

小智 5

您可以指定带有可选部分(由 分隔[])的模式,以指示偏移量可以有 2 种不同的格式,并使用@JsonFormat注释将其添加到相应的字段中。

我创建了这个测试类:

public class SampleType {

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

    // getter and setter
}
Run Code Online (Sandbox Code Playgroud)

请注意最后一部分 ( [XXX][XX]):每一对[]都是一个可选部分,因此解析器会尝试解析每一个(如果存在)。XXX与偏移:,并XX在没有它的偏移量(更多详情,请看看的javadoc

这样,两种格式都可以读取:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());

// offset with ":"
String json = "{ \"date\": \"2017-03-28T14:40:00+01:00\" }";
SampleType value = mapper.readValue(json, SampleType.class);
System.out.println(value.getDate()); // 2017-03-28T13:40Z[UTC]

// offset without ":"
json = "{ \"date\": \"2017-03-28T14:40:00+0100\" }";
value = mapper.readValue(json, SampleType.class);
System.out.println(value.getDate()); // 2017-03-28T13:40Z[UTC]
Run Code Online (Sandbox Code Playgroud)

请注意,结果ZonedDateTime的值将转换为 UTC:2017-03-28T13:40Z[UTC]

如果要保留原始偏移量,只需使用com.fasterxml.jackson.databind.DeserializationFeature该类配置ObjectMapper

// add this to preserve the same offset (don't convert to UTC)
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
Run Code Online (Sandbox Code Playgroud)

这样,偏移量将被保留(值不会转换为 UTC),并且上述测试的输出将为2017-03-28T14:40+01:00.