gpt4 book ai didi

java - 我应该将时区与 Postgres 和 JDBC 的时间戳分开存储吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:43:44 26 4
gpt4 key购买 nike

似乎(也许我错了)如果您想保留 JDBC 和 Postgres 发生某些事情时的时区,您需要将时区与时间戳分开存储。

也就是说,我更愿意给我的 ORM/JDBC/JPA 一个带有时区 America/New_York 的 Java Calendar(或 Joda DataTime) > 到 Postgres timestampz 字段。并且无论服务器时区(或默认为 UTC)如何,我都希望在检索时返回一个带有时区 America/New_YorkCalendar。但只要看看大多数 JDBC 代码(以及依赖于它但不会发生的事情)。

这是正确的吗?

当 postgres 支持时,我需要将 tz 存储在另一个字段中,这似乎很荒谬。

因此似乎只有两个选择:

  1. 选择 timestampz Postgres 列作为 java.util.String 并解析它。
  2. 将时区存储为单独的字段。

选项一和选项二需要某种类型的转换拦截器用于我的 SQL 映射/ORM 库。

  • JDBC 的最佳解决方案是什么?
  • JPA 的最佳解决方案是什么(如果不同于 JDBC)?

最佳答案

当您存储带有时区的时间戳 (timestamptz) 时,它会转换为 UTC 以存储在数据库中。检索时,它会转换为客户端的当前时区,而不是它最初所在的时区。基本上,它是一个时间点。

还有timestamp without time zone(时间戳)。这不受转换影响,但带有时间戳。如果您存储一个 timestamp 并将您的客户端时区设置为 UTC,然后在客户端时区为“+08:00”时检索它,您将获得相同的值。这是您想要的一半,因为它保留了原始时间值。

名称和行为很糟糕且令人困惑,但由 SQL 标准设置。

如果您希望记录特定时区的时间点,则必须单独存储时区。我建议将其存储为 INTERVAL 并使用 CHECK 约束将其限制为 colname BETWEEN INTERVAL '-12' HOUR + INTERVAL '1' SECOND AND INTERVAL '12' 小时。该定义拒绝 -12:00 并接受 +12:00;我不完全确定这是正确的,所以检查一下。

您可以存储该时区本地时间的 timestamp(我可能会这样做),或者存储事件发生时 UTC 时间的 timestamptz发生加上一个偏移量,让您可以将其转换为本地时间。

两者都适用于 JDBC。对于 JPA,这将取决于您的提供者对间隔类型的理解和映射程度。理想情况下,您希望实体中有一个 transient 生成字段,该字段使用存储在数据库中的 timestampinterval 重建您想要的 Calendar 实例。

关于java - 我应该将时区与 Postgres 和 JDBC 的时间戳分开存储吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12331962/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com