javaspring-mvcspring-bootjava-timejackson2

Spring boot + Jackson - Always convert dates to UTC


I'm saving the dates on my database without timestamp, so I want to standarize the way the dates are received by my Spring Boot Rest Controllers, so the services can be deployed anywhere in the world (AWS EC2, etc).

I tried to set the following properties, didn't help:

spring.jackson.time-zone=UTC

There is another property, which is always true, so I didn't set, that is:

spring.jackson.deserialization.adjust-dates-to-context-time-zone=true

I'm deploying to 2 separate Ubuntu containers, one at UTC timezone and another in my current timezone America/Sao_Paulo which is (GMT -3).

Example payload:

{"date":"2017-09-15T18:58:00.000Z"}

When the service is deployed on São Paulo, it receives:

2017-09-15 18:58:00.000000

Which is correct.

When the service is deployed on UTC, it receives:

2017-09-15 15:58:00.000000

Which is incorrect.

I'm storing the date information in Java with LocalDateTime.

Example model:

import java.time.LocalDateTime;

class Model {
    private LocalDateTime date;

    public LocalDateTime getDate() {
        return date;
    }

    public void setDate(LocalDateTime date) {
        this.date = date;
    }
}

Example resource:

@RestController
class Resource {
    @RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<?> add(@RequestBody Model model) {
        System.out.println(model.getDate());
        // persistence ommited
        return ResponseEntity.created(URI.create("")).build();
    }
}

I cannot change the timezone of all my production machines, I must solve this with Jackson and Java (if possible).

Another restriction: must not annotate my model classes to do this.

My pom.xml (relevant part)

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.3.RELEASE</version>
</parent>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.8.5</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
    <version>2.8.5</version>
</dependency>

Solution

  • I've faced a similar problem in my production environment too. I've solved it with this method in my Application.java (the class with main method):

    @PostConstruct
    void started() {
        TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
    }
    

    Hope it could help you.