我应该将时区与Postgres和JDBC的时间戳分开存储吗?
似乎(也许我错了)如果你想保留JDBC和Postgres发生事件的时区,你需要将时区与时间戳分开存储。
那就是我更愿意给我的ORM / JDBC / JPA一个Java Calendar
(或Joda DataTime
),比如说timezone America/New_York
到Postgres timestampz
字段。 并且我希望无论服务器时区(或默认为UTC)检索都能给我带回时区America/New_York
的Calendar
。 但只是查看大多数JDBC代码(以及依赖于它的事情不会发生)。
它是否正确?
当postgres支持时,我需要将tz存储在另一个字段中,这似乎很荒谬。
因此,似乎只有两个选项:
- 选择
timestampz
Postgres列作为java.util.String
并解析它。 - 将时区存储为单独的字段。
第一和第二选项需要某种转换拦截器用于我的SQL映射/ ORM库。
- 什么是JDBC的最佳解决方案?
- JPA的最佳解决方案是什么(如果与JDBC不同)?
当您存储timestamp with time zone
( timestamptz
)的timestamptz
它将转换为UTC以存储在数据库中。 检索时,它会转换为客户端的当前时区,而不是原来的时区。基本上,这是一个时间点。
还有timestamp without time zone
timestamp
( timestamp
)。 这不受转换限制,但不带有时间戳。 如果您将客户端时区设置为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,它取决于您的提供者理解的程度并映射区间类型。 理想情况下,您希望实体中的瞬态生成字段使用存储在数据库中的timestamp
和interval
重建所需的Calendar实例。
EclipseLink支持在Oracle中存储时区,我认为如果你定制了PostgreSQLPlatform,你也可以将它存储在Postgres中。