在搜索和閱讀如何處理來自Java和MySQL的日期和時間後,我仍然感到困惑。仍然困惑於Java時間戳等與MySQL
比方說,我創建了一個java.util.Date
對象。該對象以UTC保存時間。任何格式化或解析到其他時區都可以用例如java.text.SimpleDateFormat
。
現在我想將我的日期對象以UTC存儲到MySQL數據庫中。但是當我在java.sql.PreparedStatement
中使用setTimestamp()
方法時,我有點困惑。這裏有一些示例代碼,我在表中測試MySQL DATETIME和TIMESTAMP。我也用setString()
和setTimestamp()
方法插入日期。
java.sql.Connection conn = java.sql.DriverManager.getConnection("jdbc:mysql://localhost/test","user","password");
java.sql.Statement st = conn.createStatement();
String q = "DROP TABLE IF EXISTS tmp";
st.execute(q);
q = "CREATE TABLE tmp (dt_string TEXT, dt DATETIME, ts TIMESTAMP)";
st.execute(q);
java.sql.PreparedStatement pst = conn.prepareStatement("INSERT INTO tmp SET dt_string=?, dt=?, ts=?");
java.text.SimpleDateFormat utc = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utc.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("EST"));
System.out.println("Default time zone: " + java.util.TimeZone.getDefault().getID());
java.util.Date d = new java.util.Date();
System.out.println("A date: " + d);
java.sql.Timestamp t = new java.sql.Timestamp(d.getTime());
System.out.println("The timestamp: " + t);
pst.setString(1, utc.format(d));
pst.setString(2, utc.format(d));
pst.setString(3, utc.format(t));
pst.execute();
pst.setTimestamp(2, t);
pst.setTimestamp(3, t);
pst.execute();
System.out.println("Use calendar: " + utc.getCalendar().getTimeZone());
pst.setTimestamp(2, t, utc.getCalendar());
pst.setTimestamp(3, t, utc.getCalendar());
pst.execute();
conn.close();
當我運行上面的代碼時,我得到了如預期的以下輸出。
Default time zone: EST
A date: Thu Mar 22 08:49:51 EST 2012
The timestamp: 2012-03-22 08:49:51.784
Use calendar: sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
但是,當我使用MySQL命令行工具檢查數據庫中的表,我得到:
mysql> select * from tmp;
+---------------------+---------------------+---------------------+
| dt_string | dt | ts |
+---------------------+---------------------+---------------------+
| 2012-03-22 13:49:51 | 2012-03-22 13:49:51 | 2012-03-22 13:49:51 |
| 2012-03-22 13:49:51 | 2012-03-22 08:49:51 | 2012-03-22 08:49:51 |
| 2012-03-22 13:49:51 | 2012-03-22 08:49:51 | 2012-03-22 08:49:51 |
+---------------------+---------------------+---------------------+
3 rows in set (0.00 sec)
第一欄就是在那裏我存儲格式UTC日期TEXT類型。
在第一行中,我使用setString()
方法存儲日期。
在第二行中,我使用setTimestamp(i,t)
方法存儲日期。我猜JDBC在存儲它之前會自動使用默認時區(我設置爲EST)轉換日期。但是不應該總是自動地以UTC存儲TIMESTAMP。 MySQL文檔說MySQL將TIMESTAMP值從當前時區轉換爲UTC存儲,並從UTC返回到當前時區以供檢索。(問題1)。
最後,對於第三行,我使用了pst.setTimestamp(2, t, utc.getCalendar());
來存儲日期,希望驅動程序應該使用UTC時區。但顯然不是(問題2)。
我可以通過將默認時區設置爲UTC來輕鬆修復問題以便以UTC存儲日期。但是,我仍然想知道上述兩個問題正在發生什麼。
*「從UTC返回到當前時區進行檢索」*是您在輸出中看到的內容。 – 2012-03-22 18:52:52
謝謝,但你能擴展嗎? – Peter 2012-03-22 19:01:03
時間戳存儲在UTC內部,但是當您使用'mysql'客戶端輸出它們時,它們會在當地時間呈現給您,就像MySQL文檔告訴您的那樣。問題2也一樣。這裏有什麼問題? – 2012-03-22 19:01:54