如何将OffsetDateTime存储到PostgreSQL“带时区的时间戳”列

时间:2019-01-14 22:01:38

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

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

2 个答案:

答案 0 :(得分:2)

  

有什么方法可以在postgres中存储带日期时间的偏移量(+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)即将出版的科技/恐怖小说《时区规则几乎打动了我的大脑》。基于真实的故事。很快就会在书店中出现)

答案 1 :(得分:1)

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

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

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