Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson deserialize ISO8601 formatted date-time into Java8 Instant

I'm trying to deserialize an ISO8601 formatted date into Java8 java.time.Instant using Jackson. I registered JavaTimeModule with the ObjectMapper, and turned off the WRITE_DATES_AS_TIMESTAMPS setting.

However, if one tries to deserialize 2016-03-28T19:00:00.000+01:00 it will not work, because it seems that JavaTimeModule will only deserialize date-times formatted with UTC timezone offset (e.g. 2016-03-28T18:00:00.000Z). I then tried using @JsonFormat annotation like this:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC") 

And like this:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = JsonFormat.DEFAULT_TIMEZONE) 

However, neither of these work and I get an exception:

com.fasterxml.jackson.databind.JsonMappingException: Unsupported field: YearOfEra (through reference chain: org.example.Article["date"]) 

Which implies that timezone parameter is ignored and date time formatter doesn't know how to format an Instant without a timezone.

Is there a way to deserialize a ISO8601 string that's not in UTC time zone offset to Java 8 java.time.Instant using Jackson and JavaTimeModule without writing a custom deserializer?

like image 910
Krešimir Nesek Avatar asked Mar 27 '16 20:03

Krešimir Nesek


2 Answers

You need to set the explicit time zone via XXX in your modell class:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") 

(see: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html)

like image 82
Meiko Rachimow Avatar answered Oct 11 '22 15:10

Meiko Rachimow


If you want to serialize Date objects into ISO-8601, you don't need to specify a pattern at all - ISO-8601 is the default pattern. It is kind of mentioned in the JsonFormat Java doc:

Common uses include choosing between alternate representations -- for example, whether Date is to be serialized as number (Java timestamp) or String (such as ISO-8601 compatible time value) -- as well as configuring exact details with pattern() property.

[emphasasis mine] you should understand from the above text that specifying shape = STRING would mean an ISO-8601 format but you can choose something else using the pattern property.

In my experience, this always turns out a UTC date format (with the time zone rendered as +0000), which could be the default time zone in my VM (even though my operating system clock is not set to UTC).

like image 26
Guss Avatar answered Oct 11 '22 14:10

Guss