问题:在应用服务器中的正确时间,在数据库中出错。
我在中国,时区是UTC + 8 我用hibernate。实体定义如下(语言:Scala)
class CargoJournal {
@Type(`type`="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
var deliverTime: LocalDateTime = _
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable=false)
var logDate:Date = _
}
我打开hibernate日志,在我的app服务器中看到以下内容。当前时间是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错了!
答案 0 :(得分:1)
MySQL中有哪些类型的列?我怀疑它是DATETIME。这种类型不存储“时刻”,它存储“时钟上的小时”,因此可以表示不同时区的不同时刻。
当MySQL驱动程序将java.util.Date写入DATETIME列时,它必须选择一些时区来写“时钟上的小时”,因为相同的java.util.Date可能意味着不同时区的不同小时。它将小时存储在MySQL服务器本地时区中。
LocalDateTime没有这个问题,因为它就像DATETIME。它表示时钟上的小时,而不是时刻,因此年/月/日 - 小时/分钟/秒仅存储在数据库中。请注意,在hibernate日志中,LocalDateTime按原样给出,而Date旁边有时区(“CST”)。
通常,最好将时间存储在UTC中,因此请使用DateTime,而不是Date和LocalDateTime。使用jadira转换器的DateTime始终将DATETIME存储/读取为UTC。