I am having some issue with date logic which I've isolated to Jackson, the JSON serializer.
In the database and in a debug point in the application, dates are correct and everything is written using default timezone. However, in serialization 4 hours are being added. I found this could be remedied by telling Jackson specifically to use EST (it was defaulting to UTC). As below:
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss.SSSZ", timezone="America/New_York")
private Date startDate;
However, the problem is that only local is using EST and the server will be using UTC. I need Jackson to use system defaults.
Luckily, I found this similar question which is backed up by the documentation. New solution:
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss.SSSZ", timezone=JsonFormat.DEFAULT_TIMEZONE)
private Date startDate;
However, it doesn't work! I tried also timezone='DEFAULT_TIMEZONE'
and a variety of other things but in all cases the api output still seems to be 4 hours ahead of the number in the database.
Other things I have tried:
JsonFormat.DEFAULT_TIMEZONE
returns ##default
.TimeZone.getDefault().getDisplayName()
returns Eastern Standard Time
.Jackson version is 2.9.
Any suggestions?
@JsonFormat is used to specify format while serialization or de-serialization. It is mostly used with Date fields.
UTC stands for Co-ordinated Universal Time. It is time standard and is commonly used across the world. All timezones are computed comparatively with UTC as offset.
Solved my own question. Here is what I found:
JsonFormat.DEFAULT_TIMEZONE
is NOT the system default, as the documentation and SO answer suggest, but actually defaults to UTC.
org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
/**
* Override the default {@link TimeZone} to use for formatting.
* Default value used is UTC (NOT local timezone).
* @since 4.1.5
*/
public Jackson2ObjectMapperBuilder timeZone(TimeZone timeZone) {
com.fasterxml.jackson.annotation.JsonFormat
/**
* Value that indicates that default {@link java.util.TimeZone}
* (from deserialization or serialization context) should be used:
* annotation does not define value to use.
*<p>
* NOTE: default here does NOT mean JVM defaults but Jackson databindings
* default, usually UTC, but may be changed on <code>ObjectMapper</code>.
*/
public final static String DEFAULT_TIMEZONE = "##default";
Solution:
@Autowired
com.fasterxml.jackson.databind.ObjectMapper objectMapper;
and objectMapper.setTimeZone(TimeZone.getDefault())
in a config class, like so:
package path.to.config;
import ...
@Configuration
public class JacksonConfiguration {
@Autowired
public JacksonConfiguration(ObjectMapper objectMapper){
objectMapper.setTimeZone(TimeZone.getDefault());
}
}
This should set the Jackson ObjectMapper to use system default instead of Jackson default (UTC).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With