Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hibernate + spring boot store date on UTC time zone troubles

I'm making some tests to define UTC as default time zone for my application. First of all I want my datetime values to be stored with the UTC one.

According to VLAD MIHALCEA (https://vladmihalcea.com/how-to-store-date-time-and-timestamps-in-utc-time-zone-with-jdbc-and-hibernate/) and https://moelholm.com/2016/11/09/spring-boot-controlling-timezones-with-hibernate/ I have set in my properties file:

spring.jpa.properties.hibernate.jdbc.time_zone= UTC

For testing I'm using h2 database, I've created a sample entity with all java 8 dateTime Type.

In my liquibase config they are defined like this:

<column name="instant" type="timestamp"/>
<column name="local_date" type="date"/>
<column name="local_time" type="time"/>
<column name="offset_time" type="time"/>
<column name="local_date_time" type="timestamp"/>
<column name="offset_date_time" type="timestamp"/>
<column name="zoned_date_time" type="timestamp"/>

I think I'm using the good type for every fields. It's work for all fields except for "local_time" "offset_time" which are Time sql types not timestamp.

enter image description here

As you can see i added this row at 8:39am (Paris GMT+2) and timestamps have the good UTC value (6:38am). BUT both "local_time" and "offset_time" have a strange value (7:39am).

I wonder why this behaviour, if some of you have an idea why my two time fields not store values correctly.

PS: version:

  • Hibernate: 5.2.17.Final
  • Spring boot: 2.0.4.RELEASE

My sample Entity use to insert data :

import javax.persistence.*;
import java.io.Serializable;
import java.time.*;
import java.util.Objects;

@Entity
@Table(name = "avdev_myData")
public class MyData implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "instant")
    private Instant instant;

    @Column(name = "local_date")
    private LocalDate localDate;

    @Column(name = "local_time")
    private LocalTime localTime;

    @Column(name = "offset_time")
    private OffsetTime offsetTime;

    @Column(name = "local_date_time")
    private LocalDateTime localDateTime;

    @Column(name = "offset_date_time")
    private OffsetDateTime offsetDateTime;

    @Column(name = "zoned_date_time")
    private ZonedDateTime zonedDateTime;
like image 755
Avdev4j Avatar asked Sep 17 '18 08:09

Avdev4j


People also ask

Should dates be stored in UTC?

It is important that there is consistency across all your date-related data. When storing dates in the database, they should always be in UTC. If you are not familiar with what UTC is, it is a primary time standard that all the major timezones are based on. The major timezones are just offsets from UTC.

Does DateTime default to UTC?

If Server sends Date in UTC format it is automatically default to local time. That is DateTime.


1 Answers

Have a try:

@SpringBootApplication
public class YourApplication {

    @PostConstruct
    void started() {
        // set JVM timezone as UTC
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    }
}
like image 74
Bendy Zhang Avatar answered Oct 13 '22 10:10

Bendy Zhang