jackson-databind: Jackson adjusts date even though date format doesn't contain timezone

For some reason jackson adjusts the date, even though the date format doesn’t contain the timezone. E.g. @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")

Binds a string of “2018-02-15T11:43:00” to a Date of “2018-02-15 12:43:00” on my local system. Shouldn’t jackson be neutral on the timezone if it is not explicitly provided? Is it possible to configure the current version of jackson to follow the expected behavior (Date of “2018-02-15 11:43:00” in above case)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 16 (8 by maintainers)

Most upvoted comments

Just for people who are searching the same issue and have reached this ticket, if your date is such like a birthday, and you don’t care about the timezone and timestamp at all, you’d better use LocalDateTime or LocalDate instead of Date.

I don’t want to retain timezone information. I just want the deserialized Date to have exactly the same values as the string, completely ignoring the timezone problem. Can configOverrides be used for deserializion too? Or is it just for serialization?

Adding to what has been said above: The confusion here might come from the fact the even though java.util.Date has no timezone data, the output of Date.toString() uses your default timezone for displaying purposes (which is then likely also shown while debugging). But this is really only for displaying purposes; Date.getTime() will show you that regardless of your local default timezone the data will be the same. Here is an example:

Date date = new Date(0);

TimeZone.setDefault(TimeZone.getTimeZone("CET"));
System.out.println(date); // Thu Jan 01 01:00:00 CET 1970

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(date); // Thu Jan 01 00:00:00 UTC 1970

So this is just another reason why, as mentioned above, you should avoid java.util.Date and prefer the java.time.* classes.

I’ve seen some testing examples, so I’ve written a few lines in that style:

        ObjectMapper mapper = new ObjectMapper();
        Date date = mapper.readValue("\"1970-01-01T00:00:00.000\"", java.util.Date.class);

The resulting date is 1970-01-01 01:00:00 on my system, I expected it to be 1970-01-01 00:00:00.

EDIT: I’ve figured out a workaround, though it is not very nice:

        ObjectMapper mapper = new ObjectMapper();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        df.setTimeZone(TimeZone.getDefault());
        mapper.setDateFormat(df);
        Date date = mapper.readValue("\"1970-01-01T00:00:00.000\"", java.util.Date.class);

Since I’m using this in spring integration 4.x it requires me to create a modified copy of Jackson2JsonObjectMapper that sets the date format. Also the workaround breaks if the date pattern is set using annotations:

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

Is there any better way of solving this issue?