首页 > 解决方案 > PostgreSQL timestamp without timezone 和 java.util.Date with timezone 的比较

问题描述

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

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);

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

2018-03-01 18:00:00

结果now.toString()是:

Wed Aug 22 16:14:03 CEST 2018

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

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

或者这样:

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

标签: javasqlpostgresqlhibernatehql

解决方案


有趣的问题。

当 PostgreSQL 的 JDBC 驱动读取类型为 的列时timestamp without time zone,通常可以将其读取为java.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

另外,这意味着建议您明确设置 JVM 时区,以确保 JDBC 驱动程序以正确的方式重新组装timestamp without time zone数据库java.util.Date

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


推荐阅读