4

问题:应用服务器中的正确时间,数据库中的错误。

我在中国,时区是 UTC+8 我使用休眠。实体定义如下(语言:Scala)

class CargoJournal {
    @Type(`type`="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    var deliverTime: LocalDateTime = _

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable=false)
    var logDate:Date = _
}

我打开休眠日志,在我的应用服务器中查看以下内容。当前时间是 Thu Sep 13 11:08:44 CST 2012

insert into wms_history_cargo_journal (deliver_time, log_date)
binding parameter [1] as [TIMESTAMP] - 2012-09-13 11:08:44.25
binding parameter [2] as [TIMESTAMP] - Thu Sep 13 11:08:44 CST 2012

在我的数据库服务器中:

mysql> select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));
+----------------------------------------------------------------+
| timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')) |
+----------------------------------------------------------------+
| 08:00:00                                                       |
+----------------------------------------------------------------+

所以mysql时区是对的。UTC+8

从mysql中选择后:

mysql> SELECT deliver_time, log_date FROM wms_history_cargo_journal;
+---------------------+---------------------+
| deliver_time        | log_date            |
+---------------------+---------------------+
| 2012-09-13 11:08:44 | 2012-09-13 03:08:44 |
+---------------------+---------------------+

log_date 错误!

4

1 回答 1

1

MySQL 中的列有哪些类型?我怀疑现在是 DATETIME。这种类型不存储“时刻”,它存储“时钟上的小时”,因此可以表示不同时区的不同时刻。

当 MySQL 驱动程序将 java.util.Date 写入 DATETIME 列时,它必须选择某个时区来写入“时钟小时”,因为相同的 java.util.Date 在不同的时区可能意味着不同的小时。它以 MySQL 服务器本地时区的形式存储小时。

LocalDateTime 没有这个问题,因为它就像 DATETIME。它代表时钟上的小时,而不是时间,因此年/月/日-小时/分钟/秒只存储在数据库中。注意休眠日志中的 LocalDateTime 按原样给出,而 Date 旁边有时区(“CST”)。

通常,最好始终以 UTC 格式存储时间,因此请使用 DateTime,而不是 Date 或 LocalDateTime。带有 jadira 转换器的 DateTime 始终将 DATETIME 存储/读取为 UTC。

于 2012-10-02T16:04:14.380 回答