【问题标题】:Should I store the timezone separately from the timestamp for Postgres and JDBC?我应该将时区与 Postgres 和 JDBC 的时间戳分开存储吗?
【发布时间】:2012-09-02 03:43:34
【问题描述】:

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

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

这是正确的吗?

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

因此,似乎只有两个选项:

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

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

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

【问题讨论】:

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

标签: java postgresql jpa jdbc


【解决方案1】:

EclipseLink 支持将时区存储在 Oracle 中,如果您自定义 PostgreSQLPlatform,我认为您也可以将其存储在 Postgres 中。

【讨论】:

  • 我使用蹩脚的休眠,我开始讨厌它。这些天中的某一天,我将切换到纯 JDBC。
【解决方案2】:

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

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

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

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

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

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

【讨论】:

  • 存储字面时区名称而不是 tz 偏移量(即 America/New_York 而不是 -4 或 -5)可能比较理想,这样我就可以正确恢复 DST。
  • @AdamGent 在这种情况下,您可能想了解 SELECT current_setting('TIMEZONE') 以在存储时获取客户端时区。但是,验证该字段很困难,因为时区可能由客户端设置为偏移量、完整的时区名称,或者可能是非唯一的 tz 缩写,如“EST”(“Eastern States Time”,澳大利亚?或“东部标准时间”,美国?Pg 接受两者,根据timezone_abbreviations 的值在它们之间进行选择。最好以已知的形式从 Java 中获取价值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 2018-11-26
  • 2023-02-19
  • 2015-11-09
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多