2011-09-30 9 views
21

GMT + 8で実行されるMysqlはGMTで実行されるtomcatです。 datetimeをデータベースに保存すると、okと表示されます.DBでdatetime値をチェックすると、GMT値が表示されます。 しかし、私はDBから値を取得しようとすると、値が変更され、DBの値がGMT + 8と見えるので、javaは値をGMTに変更します。java接続でmysqlのタイムゾーンを変更するには

私は、接続URLは

useTimezone=true&serverTimezone=GMT 

を追加設定したが

+0

「間違った」タイムゾーンのみを取得するのか、それとも値自体が間違っていますか? – Thilo

+0

設定をuseGmtMillisForDatetimes = true&serverTimezone = GMTに変更します。私が望む行動だと思われる。まだ混乱している。 – Xilang

答えて

47

useTimezoneが古い回避策では動作しませんしてみてください。 MySQLチームはかなり最近setTimestamp/getTimestampコードを書き直しましたが、接続パラメータuseLegacyDatetimeCode = falseを設定し、最新バージョンのmysql JDBCコネクタを使用している場合にのみ有効になります。だから、たとえば:あなたは、MySQLコネクタのソースコードをダウンロードし、setTimestampを見れば

String url = 
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false 

、それは何が起こっているか見ることは非常に簡単です:

使用レガシー日付のタイムコード= falseの場合、newSetTimestampInternal(.. 。)が呼び出されます。その後newSetTimestampInternalに渡されたカレンダーがNULLであれば、あなたの日付オブジェクトがデータベースのタイムゾーンでフォーマットされています

this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US); 
this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ()); 
timestampString = this.tsdf.format(x); 

それはカレンダーがnullであることが非常に重要です - ので、あなたが使用していることを確認してください:

setTimestamp(int,Timestamp). 

... setTimestamp(int、Timestamp、Calendar)ではありません。

これはどのように動作するのかは明らかです。あなたがjava.util.Calendarを使用してsetTimestamp(1、myDate)を呼び出すと、2011年1月5日午前3時にAmerica/Los_Angeles(または任意の時間帯)を作成すると、日付が取得され、SimpleDateFormat データベースのタイムゾーンでフォーマットします。あなたのDBがAmerica/New_Yorkにあれば、(NYがLAより3時間遅れているので)文字列 '2011-01-05 6:00:00'を挿入します。

日付を取得するには、(Calendarを除く)getTimestamp(int)を使用します。もう一度、データベースのタイムゾーンを使用して日付を作成します。

注:ウェブサーバーのタイムゾーンは現在完全に無関係です! useLegacyDatetimecodeをfalseに設定しないと、Webサーバーのタイムゾーンがフォーマットに使用され、多くの混乱が生じます。


注:

これは、MySQLは、サーバーのタイムゾーンがあいまいであると文句を言う私のことが可能です。

String url = 
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York"; 

:データベースは、ESTを使用するように設定されている場合は、データベースのタイムゾーンがあり、まさにそれを伝えることにより、mysqlのコネクタのためにこれを明確にすることができますので、例えば、Javaでいくつかの可能なEST時間帯があるかもしれませんあなたが文句を言ったら、これを行う必要があります。

+0

useLegacyDatetimeCodeの提案をありがとうございました!注:これはまた、Joda Timeで働く(ユーザータイプの休止状態のアドオンを介して)私の問題を解決しました。 – Pete

+0

したがって、接続文字列にserverTimezoneとuseLegacyDatetimeCodeを追加すると、Timestmpを送信することができ、UTC時刻としてDateTime列に正しく記録されます。私はそれを私のMySQLコンソールで見ることができます。 JDBC経由でSELECTを実行してデータを取得しようとすると、JDBCレイヤーでは自動的に変換されます。私はgetObject()とgeTimestmp(UTCカレンダーオブジェクトを使用せずとも)を試してきました。ローカルタイムに戻ってきます。 – djsumdog

+0

これは生産上の問題を解決するために必要な設定だったことがわかります。ローカルでは再現できませんでした。しかし、これをドライバーで試してみると、10-30秒の処理後にストールがなくなりました。 –

関連する問題