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()
メソッドを使用して日付が格納されていました。
2番目の行には、setTimestamp(i,t)
メソッドを使用して日付が格納されていました。 JDBCは自動的に日付をデフォルトのタイムゾーン(ESTに設定)を使用して自動的に変換してから保存していると思います。しかし、TIMESTAMPは常に自動的にUTCに格納されるべきではありません。 MySQLのドキュメントによれば、は、TIMESTAMPの値を現在のタイムゾーンからUTCに変換してUTCから現在のタイムゾーンに戻して取得します。(Issue 1)
最後に、3行目では、ドライバーがUTCタイムゾーンを使用することを期待して、pst.setTimestamp(2, t, utc.getCalendar());
を使用して日付を保存しました。しかし明らかにそうではありませんでした(問題2)。
デフォルトのタイムゾーンをUTCに設定することで、日付をUTCに保存する問題を簡単に修正できます。しかし、私は上記の2つの問題について何が起こっているのかを理解したいと思います。
* "UTCから現在のタイムゾーンに戻って検索する" *は出力に表示されます。 –
ありがとうございますが、これを拡張できますか? – Peter
タイムスタンプは内部的にはUTCに保存されますが、mysqlクライアントを使用して出力すると、現地時間にMySQLドキュメントが示すように表示されます。問題2と同じです。問題は何ですか? –