问题:应用程序服务器中的时间正确,数据库中的时间错误。
我在中国,时区是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 = _
}
我打开休眠日志,在我的应用服务器中看到以下内容。当前时间是9月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 |
+---------------------+---------------------+
日志日期错误!
MySQL中的列类型有哪些?我怀疑是DATETIME。这种类型不存储"时间上的时刻",而是存储"时钟上的小时",因此可以表示不同时区的不同时刻。
当MySQL驱动程序将java.util.Date写入DATETIME列时,它必须选择某个时区来写入"hour on clock",因为相同的java.util.Date可能意味着不同时区的不同小时。它将小时存储为MySQL服务器本地时区。
LocalDateTime没有这个问题,因为它类似于DATETIME。它表示时钟上的小时,而不是时间上的时刻,因此年/月/日小时/分钟/秒只存储在数据库中。请注意,hibernate日志中的LocalDateTime是按原样给出的,而Date旁边有时区("CST")。
通常,最好始终以UTC存储时间,因此请使用DateTime,而不是Date或LocalDateTime。带有jadira转换器的DateTime始终将DateTime存储/读取为UTC。