I have a java.util.Date
object, and I need to insert it into a datetime field in MySQL in UTC
format.
java.util.Date date = myDateFromSomewhereElse;
PreparedStatement prep = con.prepareStatement(
"INSERT INTO table (t1, t2) VALUES (?,?)");
java.sql.Timestamp t = new Timestamp(date.getTime());
prep.setTimestamp(1, t, Calendar.getInstance(TimeZone.getTimeZone("PST"));
prep.setTimestamp(2, t, Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(prep.toString());
Which gives me the prepared SQL statement string:
INSERT INTO table (t1, t2) VALUES ('2012-05-09 11:37:08','2012-05-09 11:37:08');
The timestamp returned is the same timestamp regardless of the timezone I specify. It's ignoring the Calendar object with timezone that I specify. What is going on and what am I doing wrong?
TimeZones are just different ways to view a date (which is a fixed point in time). I wrote a little example here (pay close attention to the assert):
The output to this snippet is (the result will be different depending on execution date/time):
Your snippet in the question is simply not doing anything with regard to the date being stored. Usually databases are configured for a native TimeZone. I advise storing an extra field representing the TimeZone to be used when interpreting the date.
It is not (generally) a good idea to modify dates (which are essentially just milliseconds before/after a fixed point in time) as this would be a lossy modification that would be interpreted differently at different points in the year (due to daylight savings time).
Or this : http://puretech.paawak.com/2010/11/02/how-to-handle-oracle-timestamp-with-timezone-from-java/
Check this link for explanation for MySQL (and you shouldn't try to apply advices about Oracle to MySQL).
Jordan, actually you had the right idea. The problem is there's a bug in MySQL JDBC driver and the Calendar argument is completely ignored by default. Look at the source code for PreparedStatement to really see what's going on.
Notice it format's the Timestamp using the JVM's time zone. This will only work if your JVM is using UTC time zone. The Calendar object is completely ignored.
In order for MySQL to use the Calendar argument, you have to disable the legacy date/time code with the following connection option:
So you might use it when connecting to the database like this:
If you disable the legacy datetime code using the above line, then it WILL render your Timestamp in the target Calendar's time zone:
It's pretty easy to see what's going on here. If you pass in a Calendar object, it will use this when formatting the data. Otherwise, it will use the database's time zone to format the data. Strangely, if you pass in a Calendar, it will also set the time to the given Timestamp value (which seems to be pointless).