我找到了一种使用UTC时区创建我想要的日期的方法: Java Date and Daylight Saving
所以我可以创建“Sun Mar 25 02:00:00”但是当我在Hibernate中插入这个日期时,它不会写它,似乎hibernate使用了一个我无法覆盖的不同时区。
我的问题是我无法在我的Hibernate / H2数据库中插入此日期:“Sun Mar 25 02:00:00”如果我使用UTC时区也不会。
更新1: 我正在尝试插入这些值:
Sun Mar 25 01:00:00 UTC 2012
Sun Mar 25 02:00:00 UTC 2012
Sun Mar 25 03:00:00 UTC 2012
Sun Mar 25 04:00:00 UTC 2012
Sun Mar 25 05:00:00 UTC 2012
Sun Mar 25 06:00:00 UTC 2012
Sun Mar 25 07:00:00 UTC 2012
Sun Mar 25 08:00:00 UTC 2012
Sun Mar 25 09:00:00 UTC 2012
Sun Mar 25 10:00:00 UTC 2012
Sun Mar 25 11:00:00 UTC 2012
Sun Mar 25 12:00:00 UTC 2012
Sun Mar 25 13:00:00 UTC 2012
Sun Mar 25 14:00:00 UTC 2012
Sun Mar 25 15:00:00 UTC 2012
Sun Mar 25 16:00:00 UTC 2012
Sun Mar 25 17:00:00 UTC 2012
Sun Mar 25 18:00:00 UTC 2012
Sun Mar 25 19:00:00 UTC 2012
Sun Mar 25 20:00:00 UTC 2012
Sun Mar 25 21:00:00 UTC 2012
Sun Mar 25 22:00:00 UTC 2012
Sun Mar 25 23:00:00 UTC 2012
但在数据库中有以下内容:
答案 0 :(得分:1)
这是JDBC的“功能”,而不是Hibernate。因此,您可以在jdbc选项(hibernate.cfg.xml中的jdbc连接字符串)中更改此行为,而不是在Hibernate选项中。默认情况下,日期值始终保存在客户端应用程序的时区中(而不是在数据库的时区中,因为它似乎更逻辑)。例如,MySQL知道一个jdbc连接选项,它强制数据库始终以UTC格式存储日期值。我不知道H2是否知道这样的选择,可能不是。
在你的例子中,3月25日是白天的第一天。 3月25日02:00在您的时区不存在,这就是您在数据库中找不到它的原因。
如果你不想在连接字符串中有一个选项(它有一个缺点,它可能在所有数据库上都不可用),有三种可能性来解决这个问题:
在插入之前和阅读之后,您可以在程序中进行时区对话。除了正常的getter get / setMyTime()之外,你还只为Hibernate get / setHibernateMyTime()写了一个额外的getter和setter,你在那里进行时区转换,并在映射文件或注释中使用。对于时区转换,您可以使用TimeZone.getOffset()。
使用字符串代替日期。在这种情况下,您不需要进行时区转换,但必须将字符串转换为日期,反之亦然。
以UTC作为本地时间运行应用程序。如果在任何地方需要用户的本地时间,例如在用户界面中,这就有缺点。
我们在我们的申请中做了解决方案1.
答案 1 :(得分:0)
如Johanna所述,如何处理这个时区转换问题有几种选择。还有一篇文章以更详细的方式解释了这个问题,提供了更多的例子和解决方案。
考虑到上一个答案中的选项编号1,并且您不想自己编写所有代码,您可以使用一个小型开源库DbAssist
。它将java.util.Date
和java.util.Timestamp
映射到自定义UtcDateType
,它在内部覆盖setter和getter,以便每当读取或写入数据库时,它都会将数据库中的日期视为UTC时区。这是一个方便的解决方案,因为您根本没有更改实体类。
您所要做的就是添加依赖项(将5.2.2替换为您的Hibernate版本):
<dependency>
<groupId>com.montrosesoftware</groupId>
<artifactId>DbAssist-5.2.2</artifactId>
<version>1.0-RELEASE</version>
</dependency>
然后按照项目github上的安装指南中的说明应用修补程序。我不是在这里复制它,因为它根据您是否使用JPA Annotations或HBM文件映射您的实体字段而有所不同;这是一个简单的单线设置。
答案 2 :(得分:0)
你能解释一下你桌子的数据结构吗?您是否在该列中使用DATETIME或TIMESTAMP?
根据MySQL官方文档--MySQL将TIMESTAMP值从当前时区转换为UTC进行存储,然后从UTC返回到当前时区进行检索。它使用JDBC连接的当前时区进行此转换。
此行为很奇怪,但正确,“Sun Mar 25 02:00:00”在您的时区(可能是中欧)中不存在。如果您需要保存该日期,则可以将列创建为DATETIME。