По-прежнему путают временные метки Java и т. д. с MySQL

После поиска и чтения о том, как обрабатывать дату и время в/из Java и MySQL, я все еще в замешательстве.

Допустим, я создаю объект java.util.Date. Этот объект хранит время в формате UTC. Любое форматирование или синтаксический анализ в другие часовые пояса можно выполнить, например, с помощью. java.text.SimpleDateFormat.

Теперь я хочу сохранить объект даты в базе данных MySQL в формате UTC. Но когда я использую метод 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();

Когда я запускаю приведенное выше, я получаю следующий вывод, который соответствует ожидаемому.

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)

Первый столбец имеет тип 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. Но все же, я хотел бы понять, что происходит по двум вопросам выше.

7
задан Peter 22 March 2012 в 18:50
поделиться