I want to configure jackson
to output any date/time values with the following format:
spring.jackson.date-format=yyyy-MM-dd'T'HH:mm:ss
I'm fetching many database rows and return them just as a json
map.
@RestController
public class MyService {
@GetMapping
public List<Map<String, Object>> get(Param params) {
return jdbcTemplate.queryForList(sql, params);
}
}
Problem: the databases and jvm default timezone is Europe/Berlin
, thus UTC+2. Therefor jackson automatically converts any database-received java.sql.Timestamp
to UTC first (subtracts 2 hours), and then outputs them via json.
In the mysql
database itself, it's a datetime
type.
But I just want jackson to output the timestamps "as is", without prior conversion! Is that possible to skip timezone correction?
I just want to ignore the timezone without conversation. Just cut it.
You could set a time zone in the date format used by ObjectMapper
. It will be used for Date
and subclasses:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(dateFormat);
In Spring applications, to configure ObjectMapper
, you can do as follows:
@Bean
public ObjectMapper objectMapper() {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(dateFormat);
return mapper;
}
In Spring Boot you can use the property spring.jackson.time-zone
to define the timezone:
spring.jackson.time-zone: Europe/Berlin
For more details on the common application properties, refer to the documentation.
Instead of using Timestamp
, you could consider LocaDateTime
from the JSR-310. It was introduced in Java 8. The "local" date and time classes (LocalDateTime
, LocalDate
and LocalTime
) are not tied to any one locality or time zone. From the LocalDateTime
documentation:
This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
This answer will give you more details on the new date and time classes.
Jackson has a module that supports JSR-310 types. Add it to your dependencies:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9</version>
</dependency>
Then register the JavaTimeModule
module in your ObjectMapper
instance:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
Most JSR-310 types will be serialized using a standard ISO-8601 string representation. If you need a custom format, you can use your own serializer and deserializer implementation. See the documentation for details.
Finally it turned out the simples way is to just set the jacksons ObjectMapper
(which uses UTC
by defaut) timezone to the jvm defaults:
@Bean
public Jackson2ObjectMapperBuilderCustomizer init() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.timeZone(TimeZone.getDefault());
}
};
}
I'd appreciate if anybody knows how I can achieve the same by just using the spring.jackson.time-zone
application.property.
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