9

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

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

它是否正确?

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

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

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

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

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

2 回答 2

11

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

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

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

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

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

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

于 2012-09-09T11:40:01.847 回答
0

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

于 2012-09-10T17:42:30.797 回答