Java 我是否应该将时区与Postgres和JDBC的时间戳分开存储?
似乎(也许我错了)如果您想保留JDBC和Postgres发生事件时的时区,您需要将时区与时间戳分开存储 也就是说,我更愿意给我的ORM/JDBC/JPA一个JavaJava 我是否应该将时区与Postgres和JDBC的时间戳分开存储?,java,postgresql,jpa,jdbc,Java,Postgresql,Jpa,Jdbc,似乎(也许我错了)如果您想保留JDBC和Postgres发生事件时的时区,您需要将时区与时间戳分开存储 也就是说,我更愿意给我的ORM/JDBC/JPA一个JavaCalendar(或JodaDataTime),在PostgresTimesZ字段中加上时区America/New_York。我希望在检索时,无论服务器的时区如何(或默认为UTC),都能返回一个时区为美国/纽约的日历。但只要看看大多数JDBC代码(以及依赖于它的事情不会发生) 这是正确的吗? 当postgres支持tz时,我需要将它存
Calendar
(或JodaDataTime
),在PostgresTimesZ
字段中加上时区America/New_York
。我希望在检索时,无论服务器的时区如何(或默认为UTC),都能返回一个时区为美国/纽约的日历。但只要看看大多数JDBC代码(以及依赖于它的事情不会发生)
这是正确的吗?
当postgres支持tz时,我需要将它存储在另一个字段中,这似乎很可笑
因此,似乎只有两种选择:
选择timestampz
Postgres列作为java.util.String
并对其进行解析
将时区存储为单独的字段
选项1和选项2需要某种类型的转换拦截器来实现我的SQL映射/ORM库
- JDBC的最佳解决方案是什么
- JPA的最佳解决方案是什么(如果不同于JDBC)
当您存储带有时区的时间戳时(timestamptz
),它将转换为UTC以存储在数据库中。检索时,它将转换为客户端的当前时区,而不是它最初所在的时区。基本上,这是一个时间点
还有没有时区的时间戳(timestamp
)。这不需要转换,但不带有时间戳。如果在客户端时区设置为UTC的情况下存储时间戳
,然后在客户端时区为“+08:00”时检索该时间戳,则会得到相同的值。这是您想要的一半,因为它保留了原始时间值
名称和行为是可怕的和令人困惑的,但是是由SQL标准设置的
如果希望在特定时区记录时间点,则必须单独存储时区。我建议将其存储为间隔
,并使用检查
约束,将其限制为间隔'-12'小时+间隔'1'秒和间隔'12'小时之间的colname
。该定义拒绝-12:00,接受+12:00;我不完全确定那是对的,所以检查一下
您可以存储该时区的本地时间的时间戳
(我可能会这样做),或者存储事件发生时UTC时间的时间戳
,以及允许您将其转换为本地时间的偏移量
这两种方法都适用于JDBC。对于JPA,这将取决于提供商对间隔类型的理解和映射程度。理想情况下,您希望实体中有一个临时生成的字段,该字段使用存储在数据库中的时间戳和间隔来重建所需的日历实例 EclipseLink支持在Oracle中存储时区,我认为如果您自定义PostgreSQLPlatform,也可以将其存储在Postgres中。当您存储timestamptz
时,它会转换为UTC以存储在DB中。检索时,它将转换为客户端的当前时区,而不是它最初所在的时区。基本上这是一个时间点。我存储文字时区名称而不是tz偏移量(即America/New_York
而不是-4或-5)可能是最理想的,这样我就可以正确恢复DST了。@AdamGent在这种情况下,您可能想知道在存储时选择当前设置(“时区”)以获取客户端时区。不过,验证该字段很困难,因为客户端可能会将时区设置为偏移量、完整时区名称,或者设置为可能不唯一的tz缩写,如“EST”(“东部各州时间”、“澳大利亚时间”或“东部标准时间”),美国Pg接受这两种情况,并根据时区缩写的值在它们之间进行选择。最好以一种已知的形式从Java中获取值。我开始讨厌使用蹩脚的hibernate。总有一天我会转而使用纯JDBC。