【问题标题】:Comparsion between PostgreSQL timestamp without timezone and java.util.Date with timezonePostgreSQL timestamp without timezone 和 java.util.Date with timezone 之间的比较
【发布时间】:2019-01-28 20:32:17
【问题描述】:

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

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-03-01 18:00:00

【问题讨论】:

  • A java.util.Date 没有时区;这只是一个抽象的时间点。您是否尝试过运行代码以查看实际发生的情况?所以,我投票赞成第一个版本是什么。
  • @TimBiegeleisen 我已经运行了代码,其中有一本书在数据库中,出版日期为 2018-08-22 16:58:17。 now 的值为 Wed Aug 22 16:59:11 CEST 2018。提到的 book 对象已出现在结果列表中。看来,您投票正确。

标签: java sql postgresql hibernate hql


【解决方案1】:

有趣的问题。

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

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

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

2018-03-01 18:00:00

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

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

【讨论】:

  • 当您谈论“自动添加本地 JVM 时区”或“剥离时区”时,您的意思是仅添加时区信息,但没有任何额外的时间戳转换,就像它发生在不同的时区(例如数据库 UTC 时间读取转换为本地时区时间)?
猜你喜欢
  • 1970-01-01
  • 2016-04-21
  • 2017-05-23
  • 2021-07-04
  • 2020-06-19
  • 2010-12-03
  • 2010-10-09
  • 1970-01-01
  • 2012-06-21
相关资源
最近更新 更多