Java 如何为当前时区的Hibernate查询分配日期参数?

Java 如何为当前时区的Hibernate查询分配日期参数?,java,hibernate,timezone,Java,Hibernate,Timezone,将日期指定给命名的SQL参数时,Hibernate会自动将其转换为GMT时间。如何使所有日期都使用当前服务器时区 假设您有一个查询: Query q = session.createQuery("from Table where date_field < :now"); q.setDate("now", new java.util.Date()); Query q=session.createQuery(“从表中日期字段

将日期指定给命名的SQL参数时,Hibernate会自动将其转换为GMT时间。如何使所有日期都使用当前服务器时区

假设您有一个查询:

Query q = session.createQuery("from Table where date_field < :now");
q.setDate("now", new java.util.Date());
Query q=session.createQuery(“从表中日期字段<:now”);
q、 setDate(“now”,new java.util.Date());
“now”将设置为GMT时间,“new Date()”将获取当前服务器时间


谢谢。

Hibernate不知道时区。任何时区转换都应该在执行查询之前完成


例如,如果您的数据库服务器设置为CST,但用户在EST上,则需要在作为查询输入的任何时间戳上添加1小时

我们使用自定义休眠日期类型。每当我们在查询上设置参数时,我们都会使用基类或实用程序方法,以便将用户的时区传递到自定义类型参数中

您只需在查询的实用工具方法中手动调整时间即可,但通过这种方式,读入或写入数据库的日期也可以正确转换。此方法还处理数据库将日期存储在其本地时区的情况。因此,即使您在一个时区有一个用户,在另一个时区有一个数据库服务器,并且Java使用GMT,它也可以直接获得所有信息。它最终看起来像:

Properties properties = new Properties();
properties.setProperty("timeZone", databaseTimeZone);
query.setParameter("from", dateEnteredByUser, Hibernate.custom(LocalizedDateType.class, properties));

作为额外的好处,我们使用它来处理SQL Server将23:59:59.999转换为第二天的事实。在自定义类型中,我们检查并取消它。

结果表明,Hibernate不会自动将日期转换为GMT,如果您使用
query.setDate()
,它只会缩短时间,因此如果您通过“2009-01-16 12:13:14”,它将变为“2009-01-16 00:00:00”


要将时间考虑在内,您需要使用
query.setTimestamp(“date”,dateObj)

如果您需要时区同步值,您可以在HQL中使用now()。我还建议你使用Joda图书馆。它有一个hibernate插件模块。

hibernate团队已经弃用了setTimestamp(字符串名称,日期值)方法以及org.hibernate.Query接口,因为版本5.2

 /* @deprecated (since 5.2) use {@link #setParameter(int, Object)} or
    {@link #setParameter(int, Object, Type)}  instead
 */
因此,您可以使用以下代码:

import org.hibernate.query.Query;
...
Query query = session.createQuery("from Table where date_field < :now");
query.setParameter("now", new Date(), TimestampType.INSTANCE );

如果您打算将它与java 8和相关的jdbc驱动程序(如Oracle’ojdbc8.jar)以及支持的hibernate版本一起使用,那么它可能不会像预期的那样工作,因此明智的做法是使用新的java.time.LocalDate和LocalDateTime。

这也让我有点不舒服。在Oracle中,
DATE
是一个与Java的
DATE
匹配的日期和时间,而
TIMESTAMP
是一个以微秒为单位的日期和时间从类型Query is deprecatedNote这是因为它不能-结构
java.util.Date
不包含任何时区信息,它只是从epoch开始的毫秒。因此,如果您希望Hibernate将时区较少的日期转换为GMT,您还需要告诉它日期与UTC纪元的实际距离。
query.setParameter("firstMomentOfToday", new Date(), DateType.INSTANCE);