Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson loses time offset from dates when deserializing to JodaTime

I'm trying to serialize and then deserialize a Joda DateTime object using Jackson, but it doesn't deserialize the object fully. It looks like timezone information is lost.

This code:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
mapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS , false);

DateTime dt = DateTime.now();
String j = mapper.writeValueAsString(dt);
DateTime dt2 = mapper.readValue(j, DateTime.class);

System.out.println("json: " + j);
System.out.println("eq? " + (dt.equals(dt2)));
System.out.println("dates:\n" + dt + "\n" + dt2);

outputs this:

json: "2013-10-18T14:10:52.458-07:00"
eq? false
dates:
2013-10-18T14:10:52.458-07:00
2013-10-18T21:10:52.458Z

Is this by design? Is there anything I can do here, short of writing my own serializer/deserializer? I've seen a few questions about this on SO, but none that deal with this aspect specifically.

I'm using Joda 2.1 and Jackson 2.1

like image 722
Vysarat Avatar asked Oct 18 '13 22:10

Vysarat


2 Answers

Jackson must be told to not adjust the time-zone to that of the local context by:

mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);

See this issue on GitHub

like image 167
Kai Moritz Avatar answered Sep 19 '22 19:09

Kai Moritz


Yes, this is by design. JodaTime DateTimeSerializer use standard toString() method. According to JodaTime official guide toString() returns - the standard ISO8601 string for the DateTime. Also, standard DateTimeDeserializer always creates UTC datetimes.

To store TimeZone you need to store it separately with same json and use .withZone() method after deserialization or just create serializer and deserializer.

UPDATE

Version 2.2.3 have a bit extended behaviour - DateTimeDeserializer creates DateTime with timeZone taken from DeserializationContext. it may be changed with ObjectMapper.setTimeZone(). Default is TimeZone.getTimeZone("GMT")

like image 38
Viktor Aseev Avatar answered Sep 20 '22 19:09

Viktor Aseev