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

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

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

它是否正确?

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

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

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

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

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

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

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

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

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

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

两者都适用于JDBC。 对于JPA,它取决于您的提供者理解的程度并映射区间类型。 理想情况下,您希望实体中的瞬态生成字段使用存储在数据库中的timestampinterval重建所需的Calendar实例。

EclipseLink支持在Oracle中存储时区,我认为如果你定制了PostgreSQLPlatform,你也可以将它存储在Postgres中。