Hibernate日期转换

mis*_*E46 6 java timezone hibernate date jodatime

在实体中设置日期字段时,我遇到了与hibernate相关的奇怪问题.日期在java程序中被解释为UTC(我做了一个System.out以确保分配的日期是'UTC'.但是,当hibernate实际上持续存储到数据库时,日期将转换为本地时间并存储)ex .该值已在实体设置器中设置为"2009-09-09 00:08:08" - GMT持续到数据库的实际值为"2009-09-08 08:08:08" - 美国东部时间.我无法找出发生的地点和原因以及如何防止它.谢谢

PS我正在使用joda日期库并使用@ org.hibernate.annotations.Type(type ="org.joda.time.contrib.hibernate.PersistentDateTime")注释该字段

Pas*_*ent 3

但是,当 hibernate 实际持久保存到数据库时,日期会转换为本地时间并存储)例如。该值已在实体设置器中设置为“2009-09-09 00:08:08” - GMT,持久保存到数据库的实际值是“2009-09-08 08:08:08” - 美国东部时间。

好的,首先,无论您使用什么列类型在 MySQL 中存储日期(TIMESTAMP 或 DATETIME),都不存储时区。来自回复:用日期时间存储时区

  • TIMESTAMP 是自 1970 年以来的秒数,占 4 个字节。它存储为 GMT。也就是说,在存储值时应用 TZ 偏移量,然后在获取值时重新应用 TZ 偏移量。(...)

  • DATETIME 是一个 8 字节的数字字符串“yyyymmddhhmmss”。(...)

其次,除非有错误行为,否则我的理解是转换应该由服务器或 JDBC 驱动程序完成,具体取决于服务器时区设置,这样您就不会得到不一致的数据。

在这两种情况下,我的观点是,从 Java存储“2009-09-09 00:08:08” - GMT“2009-09-08 08:08:08” - 美国东部时间 应该产生相同的值数据库。

但是,显示它们时似乎进行了不同的转换。这就引出了一个问题:您如何实际检查“持久日期”的值。您的 SQL 客户端是否出现“问题”?在Java代码中?

参考


MySQL 的 DateTime 文档说“MySQL 以‘YYYY-MM-DD HH:MM:SS’格式检索并显示 DATETIME 值”。这意味着 mysql 将“自纪元以来的毫秒数”转换为上述格式。所以现在我的问题是,时区信息也存储在mysql中吗?

我已经更新了我最初的答案(并不完全准确/详尽)。无论您使用 DATETIME 还是 TIMESTAMP,答案是否定的。

我的另一个观察结果是,仅当我在 Java 应用程序中设置日期时,才会存在上述日期“转换”问题。如果我创建一个 mysql 触发器来使用“UTC_TIMESTAMP()”更新/设置日期,则日期将以“UTC”时间显示。

UTC_TIMESTAMP ()函数始终返回当前UTC日期和时间。


我想知道的是:

  • 你是如何“揭露”这个问题的?使用 SQL 客户端还是 Java?
  • JVM 的本地时区是什么?
  • MySQL 服务器时区是什么?
  • MySQL JDBC 驱动程序的版本是什么?
  • 你能用原始 JDBC 进行测试吗?