什么 Offset 用于从 Postgres timestampTZ 解组 OffsetDateTime?

What Offset is used to unmarshal an OffsetDateTime from a Postgres timestampTZ?

我确实阅读了 timestamps-and-time-zones-in-postgresql 并了解时间戳 TZ 存储为 UTC 时间戳,任何 timezone/offset 转换并丢失。

因此,当加载具有 OffsetDateTime 字段的 JPA/Hibernate 实体时,绑定到这样的 timestampTZ 字段,Offset 从何而来? 它是否总是转换为 JDBC-Connection 的时区?

这是一种信息截断,我们实际上丢失了原始时区信息,因此我们被设置回 JDBC 连接绑定到的任何时区,因此我们需要存储如果我们需要,还需要时区信息吗?

如果以上所有条件都成立,那么使用 Instant 而不是 OffsetBigTime 岂不是更好吗? 然后我至少必须在代码中显式应用 "proper timezone" 而不是通过某些数据库连接应用 "magically"...

when loading an JPA/Hibernate Entity with a OffsetDateTime-field, bound to such an timestampTZ field, where does the Offset come from

虽然我不使用 JPA 或 Hibernate(我直接使用 JDBC),但我希望您收到偏移量为零的 OffsetDateTime hours-minutes-seconds ahead/behind 世界标准时间。我们可以简称为“在 UTC”。

你自己看吧。检索 OffsetDateTime object,然后调用 toString。如果结果文本在末尾显示 +00:00Z,则表示偏移量为零。

we are required to store the timezone-information additionally if we'd needed that?

是的,如果您关心提交给数据库的时区或偏移量,您必须通过自己的额外编程将这些信息保存在第二列中。默认情况下,Postgres 使用提交的区域或偏移信息调整为 UTC,然后丢弃该区域或偏移信息。

我希望大多数商业应用程序不关心原始区域或偏移量是什么。请记住,时刻(时间轴上的点)不会改变。只有 wall-clock 时间出现不同。 Postgres 就像一个在冰岛(UTC 是他们的 year-round 永久时区)的人接到东京或蒙特利尔某人的电话。如果两个人都抬头看墙上的时钟,东京的人会比冰岛的 Postgres 人早几个小时看到一天中的时间。蒙特利尔人看到挂在自己墙上的时钟上的时间比冰岛的 Postgres 人晚了几个小时。

当您检索偏移量为零的 OffsetDateTime object 时,您可以轻松调整到您想要的任何时区。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

wouldn't it be much more clearer/precise to use Instant

是的!!

出于某种原因,控制 JDBC API 的人在 JDBC 4.2 中做出了一个奇怪的选择,要求支持 OffsetDateTime 但不需要支持 InstantZonedDateTime。在我想象的大多数应用程序中,这另外两个 classes 的使用频率更高。所以他们选择的逻辑逃避了我。

您的 JDBC driver 可能支持 InstantZonedDateTime。试试看吧。 JDBC 4.2 API 不禁止这种支持; API 没有提到这些类型。因此,对 InstantZonedDateTime 的支持是可选的。

Then I would have to at least apply the "proper timezone" explicitly in code and not have it applied "magically" by some db-connection...

如果您检索 java.time objects 到 JDBC 4.2 兼容的 drivers,我会感到非常惊讶查看他们将区域或偏移量应用于检索值。我希望您只会收到偏移量为零的 OffsetDateTime objects。但我不记得他的行为以某种方式在规范中被强制要求。因此,请始终测试您特定 JDBC driver.

的行为

请注意,以文本形式检索值或使用其他中间件工具(如 PgAdmin)可能会注入一些默认区域或偏移量。虽然 well-intentioned,但我认为这是 anti-feature,造成了特定区域已保存在数据库中的错觉,但实际上并未保存。

What Timezone is used to unmarshal an OffsetDateTime from a Postgres timestampTZ?

首先,要知道偏移只是本初子午线之前或之后的小时数、分钟数和秒数。时区要多得多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。

所以你标题的措辞自相矛盾。 OffsetDateTime 不涉及时区,因此得名。对于时区,使用 ZonedDateTime class。