我们有一个 MySQL 数据库,其中 UTC 时间戳被持久化到 DATETIME 列中。
我正在通过 Hibernate 检索这些时间(到 Date 属性中,使用 TemporalType.TIMESTAMP)并希望将它们原封不动地显示给用户。
我看到的问题是,当 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 中的内部值
我无法控制全局更改服务器的时区,并且我们的数据库中还有许多其他与时区相关的列不应更改。那么我如何告诉 Hibernate 只有一些列值是 UTC 并确保它不会对它们应用任何时区“格式”?
在 MySQL 命令行客户端中,我可以使用更改本地时区
SET TIME_ZONE='+0:00'
这允许 UNIX_TIMESTAMP() 返回一个 UTC 值,但我不知道如何告诉 Hibernate 在运行从数据库中提取信息的 Criteria/Projection 之前发送这个值。