【发布时间】:2021-06-11 13:31:59
【问题描述】:
我对将 PostgreSQL 的 TIMESTAMPTZ 类型与官方 JDBC 驱动程序一起使用感到困惑。
如果我错了,请纠正我,但 PostgreSQL 和 Java 存储 TIMESTAMTZ 和 java.util.Date 相同:作为从 Unix 开始的毫秒数,定义为 1970-01-01 00:00:00 UTC。
因此,从技术上讲,我们使用相同的 Long 值进行操作,我们应该不会遇到任何问题。
但是,我们在代码在一个或另一个方向上进行大量转换时遇到了很多问题,这些转换被更复杂的转换所取代,而这些转换恰好在之后起作用。最终结果有点类似于https://stackoverflow.com/a/6627999/5479362,在两个方向都转换为 UTC。在阻止更改时区的 Windows 下进行开发,使得调试变得不那么容易。
如果我有一个带有列的 PostgreSQL 表:
last_modified TIMESTAMP WITH TIMEZONE
我想用 Date 实例查询它:
Date modifiedAfter = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss").parse("2021-06-11 15:20:00");
PreparedStatement ps = conn.prepareStatement("Select * from mytable where last_modified > ?");
ps.setDate(1, modifiedAfter);
然后它将正常工作,因为PostgreSQL JDBC driver 将使用我的 java 程序的语言环境将 java 日期转换为 UTC Long,并且当查询该日期时数据库服务器将使用它自己的语言环境?
或者如果服务器的语言环境与客户端的语言环境不同,那么这些转换没有正确处理,因此我只需要在 UTC 日期进行操作?
我对上面链接的答案的问题是,OP 声称它“为他工作”,这意味着 Java 总是读取写入的内容,但不一定是正确存储的值在数据库中,以便其他客户端可以读取预期的内容。
上面的方法是处理 TIMESTAMTZ 以确保 both Java 代码和 PSQL 控制台中的查询输出会给出一致的结果吗?如果不是,正确的解决方案是什么?
我希望,当我使用运行 TimeZone +4 的 Java 程序编写“2021-11-06 15:00:00”时:
- 带有 TimeZone +2 的 Java 程序将获得 '2021-11-06 13:00:00'
- 带有 TimeZone +1 的 PSQL 客户端将获得“2021-11-06 12:00:00”
- 实习生,会是'2021-11-06 11:00:00'
【问题讨论】:
-
Sun、Oracle 和 JCP 社区在一致采用定义 java 的 JSR 310 时放弃了可怕的
Date、Calendar、Timestamp和SimpleDateFormat类.time 类。我建议你也转到 java.time。
标签: java postgresql timezone timestamp-with-timezone