UTC タイムスタンプが DATETIME 列に保持される MySQL データベースがあります。
これらの時間を Hibernate 経由で (TemporalType.TIMESTAMP を使用して Date プロパティに) 取得しており、変更せずにユーザーに表示したいと考えています。
私が見ている問題は、Hibernate が列の値を読み取るときに、タイムゾーン (エポックからの秒数) の値をオブジェクトの Date プロパティに割り当てることです。ただし、この値はローカル タイム ゾーンに従って保存されます。
mysql> create table datetest(mydate datetime);
Query OK, 0 rows affected (0.13 sec)
mysql> insert into datetest values('2012-07-25 16:00:00');
Query OK, 1 row affected (0.00 sec)
mysql> select mydate from datetest;
+---------------------+
| mydate |
+---------------------+
| 2012-07-25 16:00:00 |
+---------------------+
1 row in set (0.00 sec)
Hibernate 内に「datetest」オブジェクトをロードし、「mydate」値を表示すると、値が次のように表示されます。
2012-05-24T15:00:00.000+0100
私は英国にいるので、+0100 (GMT+DST) がローカル タイムゾーンです。これは UNIX_TIMESTAMP() の結果と一致します。
mysql> select unix_timestamp(mydate) from datetest;
+------------------------+
| unix_timestamp(mydate) |
+------------------------+
| 1343228400 |
+------------------------+
1 row in set (0.00 sec)
Hibernate がレコードをロードするとき、UNIX_TIMESTAMP() を使用してオブジェクトの Date プロパティを設定すると思います。UNIX_TIMESTAMP() のドキュメントには次のように記載されています。
サーバーは日付を現在のタイム ゾーンの値として解釈し、UTC の内部値に変換します。
サーバーのタイムゾーンをグローバルに変更することはできません。また、データベースには、変更してはならないタイムゾーン関連の列が他にもたくさんあります。では、一部の列の値のみが UTC であることを Hibernate に伝え、それらにタイムゾーンの「フォーマット」を適用しないようにするにはどうすればよいでしょうか?
MySQL コマンド ライン クライアント内で、次を使用してローカル タイムゾーンを変更できます。
SET TIME_ZONE='+0:00'
これにより、UNIX_TIMESTAMP() は UTC 値を返すことができますが、データベースから情報を抽出する Criteria/Projection を実行する前に、Hibernate にこの値を送信するように指示する方法がわかりません。