Kevin
Kevin

Reputation: 11662

Jackson / JavaTimeModule - handle different timezone offset formats

I'm calling an API (using Jersey) which returns Date Time with zone offset. Sometimes the data is in this format:

"2017-03-28T14:40:00+01:00"

and sometimes it is in this format (I've no control over this)

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

I want to marshal these into java.time.ZonedDateTime objects. I'm using JavaTimeModule() in my Jersey ObjectMapper.

objectMapper.registerModule(new JavaTimeModule());

The Question : Is there any way to get make the object mapper flexible enough to handle time zone offset in +01:00 or +0100?

Upvotes: 5

Views: 4166

Answers (1)

user7605325
user7605325

Reputation:

You can specify a pattern with optional sections (delimited by []), to indicate that the offset can have 2 different formats, and add this to the respective field using the @JsonFormat annotation.

I've created this test class:

public class SampleType {

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

    // getter and setter
}

Note the last part ([XXX][XX]): each pair of [] is an optional section, so the parser tries to parse each one, if present. XXX is the offset with : and XX is the offset without it (for more details, take a look at the javadoc)

With this, both formats can be read:

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]

Note that the resulting ZonedDateTime's value is converted to UTC: 2017-03-28T13:40Z[UTC]

If you want to keep the original offset, just use the com.fasterxml.jackson.databind.DeserializationFeature class to configure the ObjectMapper:

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

With this, the offset is preserved (value is not converted to UTC), and the output for the tests above will be 2017-03-28T14:40+01:00.

Upvotes: 6

Related Questions