Sau khi tìm kiếm và đọc về cách xử lý ngày và giờ đến/từ Java và MySQL, tôi vẫn còn bối rối.Vẫn còn bị nhầm lẫn bởi Java Timestamps vv với MySQL
Cho phép nói rằng tôi tạo đối tượng java.util.Date
. Đối tượng đó giữ thời gian trong UTC. Bất kỳ định dạng hoặc phân tích cú pháp nào vào các múi giờ khác đều có thể được thực hiện với ví dụ: java.text.SimpleDateFormat
.
Bây giờ tôi muốn lưu trữ đối tượng ngày tháng của tôi vào cơ sở dữ liệu MySQL trong UTC. Nhưng khi tôi sử dụng phương pháp setTimestamp()
trong java.sql.PreparedStatement
Tôi thấy hơi bối rối. Dưới đây là một số mã mẫu nơi tôi thử nghiệm cả hai DATETIME MySQL và TIMESTAMP trong bảng của tôi. Tôi cũng chèn ngày với cả hai phương thức setString()
và 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();
Khi tôi chạy ở trên, tôi nhận được kết quả như mong đợi.
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]
Nhưng khi tôi kiểm tra bảng trong cơ sở dữ liệu bằng cách sử dụng công cụ dòng lệnh MySQL tôi nhận được:
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)
Cột đầu tiên chỉ là một loại TEXT nơi tôi lưu trữ các UTC ngày định dạng.
Trong hàng đầu tiên, tôi đã lưu trữ ngày bằng phương pháp setString()
.
Trong hàng thứ hai, tôi đã lưu ngày bằng phương pháp setTimestamp(i,t)
. Tôi đoán rằng JDBC sẽ tự động chuyển đổi ngày sử dụng múi giờ mặc định (mà tôi đặt thành EST) trước khi nó lưu trữ nó. Nhưng không nên TIMESTAMP luôn tự động được lưu trữ trong UTC. Tài liệu MySQL cho biết MySQL chuyển đổi giá trị TIMESTAMP từ múi giờ hiện tại sang UTC để lưu trữ và ngược lại từ UTC thành múi giờ hiện tại để truy xuất. (Số phát hành 1).
Cuối cùng, đối với hàng thứ ba, tôi đã sử dụng pst.setTimestamp(2, t, utc.getCalendar());
để lưu ngày với hy vọng người lái xe nên sử dụng múi giờ UTC. Nhưng dường như không (Vấn đề 2).
Tôi có thể dễ dàng khắc phục vấn đề để lưu trữ ngày trong UTC bằng cách đặt múi giờ mặc định thành UTC. Tuy nhiên, tôi vẫn muốn hiểu những gì đang xảy ra cho hai vấn đề trên.
* "quay lại từ UTC đến múi giờ hiện tại để truy xuất" * là những gì bạn thấy ở đầu ra. –
Cảm ơn bạn, nhưng bạn có thể mở rộng về điều này không? – Peter
Dấu thời gian được lưu trữ trong UTC nội bộ, nhưng khi bạn xuất chúng bằng cách sử dụng trình khách 'mysql', chúng được hiển thị cho bạn theo giờ địa phương, như tài liệu MySQL cho bạn biết. Tương tự cho vấn đề 2. Vấn đề ở đây là gì? –