maximus maximus - 9 months ago 63
Java Question

Java Date in hibernate mapping from DB (timezone issue and daylight savings)

I have read many answers on similar question but still can't understand the whole logic.
My aim is to handle date (including time, not just year month etc) inside of my application and consider the daylight savings time shift and server's timezone as well. I am using hibernate and postgresql db. My mistake was to use
java.util.Date type for all the dates coming from DB. Soon I realized that it doesn't contain timezone information. Now the question arises, how to use correct Date (daylight and timezone considered)?

What would be the correct way to do it? Using different type of class such as Calendar? Or just leave it as it is but at every place where I use Date I should convert it to local timezone with Calendar for example?

What makes me confused is how the date comes from db into the Date object and if its safe to convert that Date object to Calendar to include timezone etc.?

Answer Source

It is not really true that java.util.Date does not carry a timezone information. By convention it is a UTC timestamp (okay, it is not really because the Javadoc states it skips the leap seconds).

However, you are quite fine if you assume it is UTC, at least the Calendar.getTime() method does.

Using the Calendar instead of Date within the application logic for building/creating the Date instances is a good first step. Use the Calendar methods setTimeZone to manage the timezone within your application, it will recompute the field values like HOUR_OF_DAY for you.

Hibernate uses JDBC to execute the SQL statements, so it is bound to the possibilities of the JDBC API and the behaviour of the JDBC driver you use and of cause the possibilities of the database.

My experience is that the JDBC drivers and the databases do differ in the Date/Time handling, espacially when it comes to timezone. postgres sql for example has date/time field type with and without timezone. Unfortunatly the types with timezone are not part of the SQL spec., so they are not part of the JDBC spec. and so Hibernate does not support them out of the box.

Long explanation for a short answer: The most common approach to solve this issue is to make sure you always store and load your data from Hibernate with the same timezone. A easy way is using UTC timezone for it, because the Calendar.getTime() method always returns the current time as UTC Date instance, which you may directly pass to Hibernate. Loading values from database, you convert them to Calendar using Calendar.setTime(Date) method.