如何防止在将“没有时区的时间戳”加载到 LocalDateTime 时考虑 JVM 时区

问题描述 投票:0回答:1

将“没有时区的时间戳”加载到 LocalDateTime 时,会考虑 JVM 时区,这会导致时间戳发生偏移。

数据库专栏:

some_timestamp timestamp without time zone

JPA 实体:

@Column(name = "some_timestamp ", columnDefinition = "TIMESTAMP")
private LocalDateTime someTimestamp;

如果数据是通过例如加载的pgAdmin 你会得到实际的时间戳。但是,如果通过 pgjdbc 驱动程序加载数据,则时间戳会根据 JVM/系统时区进行修改。

示例:

system timezone: UTC+01:00 Amsterdam, Berlin, ...
database value: '2018-03-25 02:00:00'
pgAdmin select result: '2018-03-25 02:00:00'
pgjdbc driver result: '2018-03-25 03:00:00'

我读到 pgjdbc 驱动程序中存在另一个方向的错误修复(用于从 LocalDateTime 转换为“无时区的时间戳”)。 请参阅 https://github.com/pgjdbc/pgjdbc/issues/2850 以及 2852 中的实际修复。

但是,我的问题是“没有时区的时间戳”到 LocalDateTime 的方向。

有谁知道如何防止jdbc驱动程序考虑JVM/系统时区?

postgresql hibernate spring-data pg-jdbc
1个回答
0
投票

好吧,根据您指定的票证,并进一步阅读,这是预期的行为。

JDBC 2.1 指定驱动程序使用默认日历 时间戳不提供时区。第 10.5 节关于日期, 时间和时间戳。

由于没有显式向 getDate() 提供日历,因此 默认 时区(实际上是默认日历)由 JDBC 驱动程序使用 内部创建适当的毫秒值假设 底层数据库不存储时区信息。

所以,除非我们提供默认的 java.util.Calendar,否则 PostgreSQL 将使用默认值,它会回退到底层 JVM 时区。


Vlad Mihalcea 参考:

传统上,为了解决这个问题,应该设置 JVM 时区 至 UTC:

声明式:

java -Duser.timezone=UTC ...

或以编程方式:

TimeZone.setDefault( TimeZone.getTimeZone( "UTC" ) );

或者如果使用 Hibernate:

hibernate.jdbc.time_zone SessionFactory-level configuration property

请参阅以下 2 个链接以帮助进一步澄清这一点。

https://github.com/pgjdbc/pgjdbc/issues/1108#issuecomment-559508740

https://in.relation.to/2016/09/12/jdbc-time-zone-configuration-property/

© www.soinside.com 2019 - 2024. All rights reserved.