Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否应该将时区与Postgres和JDBC的时间戳分开存储?_Java_Postgresql_Jpa_Jdbc - Fatal编程技术网

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

Java 我是否应该将时区与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时,我需要将它存

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

也就是说,我更愿意给我的ORM/JDBC/JPA一个Java
Calendar
(或Joda
DataTime
),在Postgres
TimesZ
字段中加上时区
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。