How to Store Date/Time and Timestamps in Utc Time Zone with JPA and Hibernate

How to store date/time and timestamps in UTC time zone with JPA and Hibernate

Since Hibernate 5.2, you can now force the UTC time zone by adding the following configuration property into the properties.xml JPA configuration file:

<property name="hibernate.jdbc.time_zone" value="UTC"/>

If you're using Spring Boot, then add this property to your application.properties file:

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

hibernate + spring boot store date on UTC time zone troubles

I opened an issue in the hibernate bug tracker and had an answer of my problem.

For LocalTime the tranformation is relative to the 1st january 1970 not the day i had run the test. So the DST is not handled.

According to Vlad Mihalcea we have to use LocalDateTime instead because we know the date and of course if it's on DST period or not.

there is the whole response here:
https://hibernate.atlassian.net/browse/HHH-12988?focusedCommentId=103750&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-103750

regards

What time zone does Hibernate use when it reads and writes a Java Calendar object to an SQL TIMESTAMP?

When Hibernate writes a Java Calendar object to an SQL TIMESTAMP column, to which time zone does it adjust the date, that of the computer or that specified in the calendar object (or some other)?

Hiberante 3.x uses the following in the CalendarType (see HB-1006):

public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
final Calendar cal = (Calendar) value;
//st.setTimestamp( index, new Timestamp( cal.getTimeInMillis() ), cal ); //JDK 1.5 only
st.setTimestamp( index, new Timestamp( cal.getTime().getTime() ), cal );
}

So Hibernate uses PreparedStatement#setTimestamp(int, Timestamp, Calendar) which uses the time zone of the calendar.

When Hibernate reads the TIMESTAMP into the calendar object, to which time zone does it translate the date?

Well, again, let's look at the CalendarType class:

public Object get(ResultSet rs, String name) throws HibernateException, SQLException {

Timestamp ts = rs.getTimestamp(name);
if (ts!=null) {
Calendar cal = new GregorianCalendar();
if ( Environment.jvmHasTimestampBug() ) {
cal.setTime( new Date( ts.getTime() + ts.getNanos() / 1000000 ) );
}
else {
cal.setTime(ts);
}
return cal;
}
else {
return null;
}

}

So Hibernate constructs a default GregorianCalendar using the current time in the default time zone with the default locale.


As a side note, I highly suggest to read the following question:

  • Daylight saving time and Timezone best practices

How do I prevent Hibernate from converting ZonedDateTime to UTC when persisting to PostgreSQL `timestamp with time zone`

In Postgres a TIMESTAMP WITH TIME ZONE actually stores its dates in UTC format in the database.

The "with time zone" means that it expects a timezone to be specified during insertion, and it will convert the specified time to UTC. By doing so, it normalizes all timestamps, which makes sense if you want to compare or sort dates.

So, the database won't store the timezone, and you'll need another way to store or determine it.

All timezone-aware dates and times are stored internally in UTC. (PostgreSQL documentation)

You could regard a timezone more like a kind of "formatting" for your user. Each user can have its own timezone, and the same date should then just be formatted in a different way. It's still the same value, it's just displayed in a different way.

From that regard, it probably makes sense to just store a timezone in the settings or profile of your user.

In my opinion the formatting of this should not even be done by an API. It should be done by the front-end. If the user doesn't have a timezone set in his user preferences, you could in fact use the timezone of the operating system of the client or the timezone of the webbrowser.



Related Topics



Leave a reply



Submit