[我确实读过timestamps-and-time-zones-in-postgresql,并且了解到timestampTZ是作为UTC时间戳存储的,任何时区/偏移都被转换掉并丢失了。
因此,当加载带有OffsetDateTime字段的JPA /休眠实体时,绑定到这样的timestampTZ字段时,偏移量来自何处?是否总是将其转换为JDBC连接的时区?
这是一种信息截断,实际上我们会丢失原始的时区信息,因此,我们将其设置回绑定到JDBC连接的任何时区,因此,如果我们需要另外存储时区信息,需要吗?
如果以上所有条件都成立,那么使用Instant而不是OffsetBigTime来更清晰/精确吗?OffsetBigTime代表的是UTC时间点,就像timestampTZ所做的一样?然后,我至少必须在代码中显式地应用“适当的时区”,而不是通过某些数据库连接来“魔术地”应用它...
当加载带有OffsetDateTime字段的JPA /休眠实体时,绑定到这样的timestampTZ字段,偏移量来自哪里
虽然我不使用JPA或Hibernate(我使用直接JDBC),但我希望您收到一个OffsetDateTime
,其中偏移量是UTC之前/之后的零小时-分钟-秒。我们可以简称为“在UTC”。
您可以自己看。检索OffsetDateTime
对象,然后调用toString
。如果结果文本的末尾显示+00:00
或Z
,则hat表示偏移量为零。
如果需要,我们还需要存储时区信息?
是的,如果您关心提交给数据库的时区或偏移量,则必须使用自己的额外编程将这些信息自己保存在第二列中。默认情况下,Postgres使用提交的区域或偏移量信息调整为UTC,然后丢弃该区域或偏移量信息。
[我希望大多数商务应用都不在乎原始区域或偏移量。请记住,时刻(时间轴上的点)没有改变。仅挂钟时间显示不同。 Postgres就像冰岛的一个人(UTC是他们全年的永久时区),接到东京或蒙特利尔某个人的电话。如果两个人都抬头看着墙上的时钟,那么东京的人会比冰岛的Postgres人早几个小时。蒙特利尔人看到一天的时间挂在继承人自己的墙上,比冰岛的Postgres人晚几个小时。
当您检索偏移为零的OffsetDateTime
对象时,可以轻松调整到所需的任何时区。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
使用Instant会更清晰/精确吗?>
是的!
出于任何原因,控制JDBC API的人在JDBC 4.2中做出了奇怪的选择,要求支持OffsetDateTime
,但不需要支持Instant
或ZonedDateTime
。我想象中的大多数其他应用中,经常更经常使用这另外两个类。因此,他们选择的逻辑使我逃脱了。
您的JDBC驱动程序可能支持Instant
ZonedDateTime
。只是尝试看看。 JDBC 4.2 API并不禁止这种支持。 API没有提及这些类型。因此,Instant
或ZonedDateTime
的支持是可选的。 然后,我必须至少在代码中显式地应用“适当的时区”,而不必通过某些数据库连接“神奇地”应用它……
如果要通过兼容JDBC 4.2的驱动程序检索
java.time
对象,看到它们将区域或偏移量应用于检索到的值,我会感到非常惊讶。我希望您只会收到偏移量为零的OffsetDateTime
对象。但是我不记得他的行为是规范中规定的一种方法。因此,请始终测试您特定的JDBC驱动程序的行为。请注意,以文本形式获取值或使用其他中间件工具(例如PgAdmin)可能会注入一些默认区域或偏移量。尽管出于很好的意图,但我认为这是一种反功能,造成了一种幻觉,即某个特定区域实际上并没有保存在数据库中。使用哪个时区从Postgres timestampTZ解组OffsetDateTime?首先,要知道偏移量只是本初子午线之前或之后的小时,分钟和秒数。时区更多。时区是特定地区人民过去,现在和将来对偏移量的更改的历史记录。
因此标题的用语是矛盾的。
OffsetDateTime
没有涉及任何时区,因此没有名称。对于时区,请使用ZonedDateTime
类。