【问题标题】:How to read timezone from 'timestamp with time zone' column?如何从“带有时区的时间戳”列中读取时区?
【发布时间】:2015-08-27 10:25:46
【问题描述】:

我无法找到一种方法来读取 PostgreSQL 列中的时区值,类型为 timestamp with time zone

JDBC 提供方法java.sql.ResultSet#getTimestamp(int, java.util.Calendar) 但我必须提供我自己的日历。我没有办法从我正在阅读的时间戳字段中获取该日历。

我正在研究存储多个时区的时间数据的系统。我需要使用时区信息保存数据,并能够从数据库中读取该时区。

没有像这样的黑客有可能吗

  • 将时区值存储在另一个字段中
  • 将日期存储为字符串,例如“Wed 17 Dec 07:37:16 1997 PST”

我使用的是 JDBC 41(JDBC4 Postgresql 驱动程序,版本 9.4-1201),java 8。

【问题讨论】:

    标签: java postgresql jdbc timestamp-with-timezone


    【解决方案1】:

    接受的答案是真实准确的。 timestamp with time 类型在字段中不存储时区信息,无法提取。

    如果对时间戳的时区感兴趣,必须单独存储(在其他字段中,或在自定义列类型中)。

    乍一看,似乎可以使用函数extract(timezone from field)timestamp with timezone中提取时区,但事实并非如此。

    该函数仅给出“与 UTC 的时区偏移,以秒为单位”。重要(文档中未说明)部分是 偏移量是从当前时区测量的(由会话 SET SESSION TIME ZONE 设置,如果未设置,则由服务器时区设置)。保存字段时使用的不是偏移量。

    【讨论】:

    • [1] 这个理解是正确的。关于您的问题的措辞,将输入/源数据的时区存储在另一个字段/列中根本不是一种技巧,如果您真的对原始区域感兴趣,那是正确且合乎逻辑的方法。 [2] 大提示: 避免使用 java.util.Date 和 .Calendar。学习在 Java 8 及更高版本和/或 Joda-Time 中使用 java.time 包。
    • 谢谢,现在我明白为什么时区必须存储在另一个字段中了。我更愿意将时区与我的时间戳值一起存储。 'timestamp with timezone' 是 db 数据类型的非常不幸的名称 - 它看起来像存储时区。 Java 8 提供了 ZonedDateTime 类来存储带有时区的日期时间。
    • 是的,SQL 类型 TIMESTAMP WITH TIME ZONE(和 WITHOUT)的命名很糟糕。我认为它是“尊重时区的时间戳”。任何伴随输入日期时间的时区信息都用于在 WITH 类型中调整为 UTC,但在 WITHOUT 类型中被忽略。对于数据库的输出也是一样,SQL 会话的当前时区设置应用于来自 WITH 类型的值,但不适用于 WITHOUT 类型。 WITHOUT 类型表示没有特定时区的“本地”日期时间值,例如说圣诞节从今年 12 月 25 日午夜开始——不同时区的每个地方的不同时刻。
    • 详情请参阅Postgres doc(无论您的数据库如何)。
    【解决方案2】:

    PostgreSQL 文档 here 说:

    对于timestamp with time zone,内部存储的值始终采用 UTC(通用协调时间,传统上称为格林威治标准时间,GMT)。

    所以没有必要“存储时区[对应于时间戳值]”本身timestamp with time zone 值始终存储为 UTC。

    此外,无需“从时间戳字段获取日历”。日历的目的是让您定义希望在 Java 应用程序中使用的特定时区。

    换句话说,timestamp with timezone 不存储来自不同时区的值(例如,一些在 EST,另一些在 PST 等),它会在插入时间戳值时将所有内容转换为 UTC。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 2021-02-08
      • 2019-11-20
      • 2013-10-04
      • 2012-04-09
      • 2013-08-17
      • 2021-12-26
      相关资源
      最近更新 更多