不带时区的 PostgreSQL 时间戳和带时区的 java.util.Date 之间的比较

Cza*_*rek 3 java sql postgresql hibernate hql

我想知道将如何执行以下查询中的比较:

StringBuilder queryStr = new StringBuilder();
queryStr.append("SELECT o FROM PRDBook as o WHERE ")
        .append("o.publicationDate < :now");

Query query = entityManager.createQuery(queryStr.toString());
Date now = new Date();
query.setParameter("now", now);
Run Code Online (Sandbox Code Playgroud)

在数据库中,列的publicationDate类型为timestamp without time zone。此列中的示例值:

2018-03-01 18:00:00
Run Code Online (Sandbox Code Playgroud)

结果now.toString()是:

Wed Aug 22 16:14:03 CEST 2018
Run Code Online (Sandbox Code Playgroud)

是否会以这种方式进行上述数据之间的比较:

2018-03-01 18:00:00 < 2018-08-22 16:14:03

或者那样:

2018-03-01 18:00:00 < 2018-08-22 14:14:03

The*_*ler 5

有趣的问题。

当 PostgreSQL 的 JDBC 驱动程序读取类型为 的列时timestamp without time zone,它通常可以将其读取到 ajava.sql.Timestampjava.util.Date

如果您选择将其读入java.util.Date(您的情况)PostgreSQL 的 JDBC 驱动程序,则会自动将本地 JVM 时区添加到其中。这是有道理的,因为类型列的整个点timestamp without time zone都被视为“本地”时间戳。

相反,当您将 a 发送java.util.Date到数据库时,它会立即删除时区。因此查询条件将采用以下形式:

2018-03-01 18:00:00 < 2018-08-22 16:14:03

Collat​​erally,这种方式我们建议您设置JVM时区明确,以确保JDBC驱动程序重装数据库timestamp without time zonejava.util.Date正确的方法。

否则,不同时区的不同服务器读取同一数据库中的同一行时,会将时间戳解释为不同的时刻。尽管如此,对于使用“本地”时间戳的应用程序来说,这可能不是一个有效的用例。