【问题标题】:How to store OffsetDateTime to PostgreSQL "timestamp with time zone" column如何将 OffsetDateTime 存储到 PostgreSQL“带时区的时间戳”列
【发布时间】:2019-01-14 22:01:37
【问题描述】:

我正在尝试使用 JDBC 将 OffsetDateTime("2019-01-14 21:10:00.02+03") 与时区 (+03) 一起存储到 PostgreSQL。 但是当使用 sql 查询检索数据时,我总是得到 +00 结果。 有什么方法可以在 postgres 中使用 datetime 存储偏移量(+03)?

【问题讨论】:

标签: java postgresql jdbc java-time timestamp-with-timezone


【解决方案1】:

有什么方法可以在 postgres 中使用 datetime 存储偏移量(+03)?

是的,但正如@Andreas 所说,偏移量必须在单独的列中。 PostgreSQL 中的列类型名称timestamp with time zone 有点误导;真的只是timestamp converted to utc。原始偏移量与时间戳值一起存储。

现在您可能想添加一个新的varchar 列并将偏移量保存为hh:mm 字符串,例如,

id  twtz                    twtz_offset
--  ----------------------  -----------
 1  2019-01-15 07:00:00+00  -07:00

但实际上最好使用ZoneOffset#getTotalSeconds() 提取偏移量以秒为单位 并将其存储在integer 列中,例如,

id  twtz                    twtz_offset
--  ----------------------  -----------
 1  2019-01-15 07:00:00+00       -25200

因为该数字可以直接应用于 UTC 值以转换回原始 OffsetDateTime,而无需将偏移量从 String 转换为 int

OffsetDateTime odtRetrieved = rs.getObject("twtz", OffsetDateTime.class);  // always UTC for PostgreSQL
// odtRetrieved is 2019-01-15T07:00Z
OffsetDateTime odtOriginal = odtRetrieved
        .toInstant()
        .atOffset(ZoneOffset.ofTotalSeconds(rs.getInt("twtz_offset")));
// odtOriginal is 2019-01-15T00:00-07:00

而且它还提供了一些额外的稳健性,以防您发现自己处理一个实际上不是一整分钟的古怪偏移。

(如果您认为这永远不会发生,请留意 Jon Skeet 即将出版的科技/恐怖小说“时区规则几乎打破了我的大脑”。根据真实故事改编。即将在书店上市.)

【讨论】:

    【解决方案2】:

    Postgres 以 UTC 存储所有内容,并且不保留原始时区。

    with timezone 只是表示该值将为您转换为会话时区,这在 JDBC 上下文中没有意义,因此您始终获取 UTC 的值。

    如果您需要存储时区偏移量,则需要自己将其存储在单独的列中。

    【讨论】:

    • 谢谢@Andreas,我会将它存储在单独的列中(((
    猜你喜欢
    • 2020-10-17
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 2014-01-25
    • 2013-10-04
    • 2013-03-27
    • 2014-01-24
    相关资源
    最近更新 更多