I have this date in a PostgreSQL 9.1 database in a timestamp without time zone column:
2012-11-17 13:00:00
It’s meant to be in UTC, and it is, which I’ve verified by selecting it as a UNIX timestamp (EXTRACT epoch).
int epoch = 1353157200; // from database
Date date = new Date((long)epoch * 1000);
System.out.println(date.toGMTString()); // output 17 Nov 2012 13:00:00 GMT
However, when I read this date using JPA/Hibernate, things go wrong. This is my mapping:
@Column(nullable=true,updatable=true,name="startDate")
@Temporal(TemporalType.TIMESTAMP)
private Date start;
The Date I get, however, is:
17 Nov 2012 12:00:00 GMT
Why is this happening, and more importantly, how can I stop it?
Note that I just want to store points in time, universally (as java.util.Date does), and I couldn’t care less about timezones, except that I obviously don’t want them to corrupt my data.
As you’ve probably deduced, the client application which connects to the database is in UTC+1 (Netherlands).
Also, the choice for the column type timestamp without time zone was made by Hibernate when it automatically generated the schema. Should that maybe be timestamp with time zone instead?
If a database does not provide timezone information, then the JDBC driver should treat it as if it is in the local timezone of the JVM (see PreparedStatement.setDate(int, Date)):
The Javadoc and the JDBC specification do not explicitly say anything about
ResultSetetc, but to be consistent most drivers will also apply that rule to dates retrieved from the database. If you want explicit control over the timezone used, you will need to use the variousset/getDate/Time/Timestampmethods that also accept aCalendarobject in the right timezone.Some drivers also provide a connection property allowing you to specify the timezone to use when converting to/from the database.