Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson @JsonFormat set date with one day less

I have been used Spring Date Rest with Spring Boot in my project. This project has a object and I have used the annotation @JsonFormat to format the date field that will be received from my Json. The format of field Date is "dd/MM/yyyy". When I send in my json the value "08/07/1980" the Jackson convert to the value "07/07/1980".

The problem is that @JsonFormat set the date with one day less

This is my source code

@Temporal(TemporalType.DATE)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "UTC")
private Date birthDate;

Thanks

like image 319
William Miranda Avatar asked Aug 05 '15 03:08

William Miranda


People also ask

What is@ JsonFormat annotation?

@JsonFormat is a Jackson annotation that we use to specify how to format fields and/or properties for JSON output. Specifically, this annotation allows us to specify how to format Date and Calendar values according to a SimpleDateFormat format.

How does Jackson deserialize dates from JSON?

How to deserialize Date from JSON using Jackson. In order to correct deserialize a Date field, you need to do two things: 1) Create a custom deserializer by extending StdDeserializer<T> class and override its deserialize(JsonParser jsonparser, DeserializationContext context) method.

What is the default Date format in Jackson?

It's important to note that Jackson will serialize the Date to a timestamp format by default (number of milliseconds since January 1st, 1970, UTC).


3 Answers

Use this solution, it is more effective and modern than my solution: https://stackoverflow.com/a/45456037/4886918

Thanks @Benjamin Lucidarme.

I resolved my problem using:

@Temporal(TemporalType.DATE) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "Brazil/East") private Date birthDate; 

I changed timezone to "Brazil/East" or "America/Sao_Paulo" and working now

Thanks

like image 82
William Miranda de Jesus Avatar answered Sep 27 '22 00:09

William Miranda de Jesus


@William's answer works but you should add theses lines to your application.properties files instead:

spring.jackson.time-zone=Brazil/East
spring.jackson.locale=pt-BR

In that way, you indicate the time-zone and locale only one time, and it applicate to all the Date of your application.

like image 45
Benjamin Lucidarme Avatar answered Sep 26 '22 00:09

Benjamin Lucidarme


I'd go with setting ObjectMapper timezone as default JVM timezone:

    ObjectMapper objectMapper = new ObjectMapper();
    //Set default time zone as JVM timezone due to one day difference between original date and formatted date.
    objectMapper.setTimeZone(TimeZone.getDefault());

It's a better solution if you don't know what timezone is used on a server environment.

In spring-boot environment you can override default JacksonAutoConfiguration:

@Bean
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    return builder.createXmlMapper(false)
            // Set timezone for JSON serialization as system timezone
            .timeZone(TimeZone.getDefault())
            .build();
}
like image 35
Michał Stochmal Avatar answered Sep 25 '22 00:09

Michał Stochmal