Pet*_*ter 7 java mysql datetime timestamp
在搜索和阅读如何处理来自Java和MySQL的日期和时间后,我仍然感到困惑.
让我们说我创建了一个java.util.Date对象.该对象保留UTC时间.任何格式化或解析到其他时区都可以用例如java.text.SimpleDateFormat.
现在我想将我的日期对象以UTC格式存储到MySQL数据库中.但是当我使用这个setTimestamp()方法时,java.sql.PreparedStatement我有点困惑.下面是一些示例代码,我在表中测试了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();
Run Code Online (Sandbox Code Playgroud)
当我运行上面的操作时,我得到以下输出,这是预期的.
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]
Run Code Online (Sandbox Code Playgroud)
但是当我使用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)
Run Code Online (Sandbox Code Playgroud)
第一列只是一个TEXT类型,我存储UTC格式的日期.
在第一行中,我使用该setString()方法存储日期.
在第二行中,我使用该setTimestamp(i,t)方法存储了日期.我想在存储它之前,JDBC会使用默认时区(我设置为EST)自动转换日期.但是TIMESTAMP不应该总是自动存储在UTC中.MySQL文档说MySQL将TIMESTAMP值从当前时区转换为UTC进行存储,然后从UTC返回到当前时区进行检索.(问题1).
最后,对于第三行,我使用它pst.setTimestamp(2, t, utc.getCalendar());来存储日期,希望驱动程序应该使用UTC时区.但显然不是(问题2).
我可以通过将默认时区设置为UTC来轻松解决以UTC格式存储日期的问题.但是,我仍然想了解上述两个问题的进展情况.
一旦您了解了 MySql 日期时间字段,它们就会变得非常棒。
您正在使用的“SimpleDateFormat”没有附加时区,因此您的数据库假定您正在输入服务器时区中的日期。如果您位于 -0500 时区,它会增加 5 小时以将其转换为 UTC,然后当您获取它时,它会减去 5 小时以将其转换回您的本地时间。
当您在插入时间戳之前将其转换为 utc 时,您仍然没有在字符串上添加时区。您的数据库对其执行了相同的操作。2012-03-22 13:49:51 添加了 5 小时,因此您的数据库存储了 2012-03-22 18:49:51 (仍然假设 -0500)。
这一切真正有趣的部分是,您可以在数据库连接上设置时区,并且您获取或插入的所有日期时间都将随着您的连接而变化!