UTC时间戳 -> java.sql.Timestamp -> jOOQ -> 在PostgreSQL中的本地时间戳?

3

我所处的时区是GMT+1,我有一个UTC时间戳(11:12:56)存储在一个long变量中。

long ts = 1487157176450;

我从这个时间戳初始化了一个java.sql.Timestamp

Timestamp timestamp = new Timestamp(ts);

然后,我使用jOOQ将这个时间戳插入到PostgreSQL(v9.4)数据库中。

create.insertInto(TABLE,
    TABLE.NAME, TABLE.TS)
  .values("Foo bar", timestamp);
然而,当我记录实际执行的SQL命令时,我看到了这个:
< 2017-02-15 10:50:37.326 CET >LOG:  execute <unnamed>: insert into "database"."table" ("name", "ts") values ($1, cast($2 as timestamp))
< 2017-02-15 10:50:37.326 CET >DETAIL:  parameters: $1 = 'Foo bar', $2 = '2017-02-15 12:12:56.450'

我不确定时间戳何时被转换为本地时间,但除非pgAdmin是在撒谎,否则我实际上在数据库中存储的是GMT+1时间戳,而不是我原本想要的UTC。

现在,由于我没有使用JDBC,所以链接问题的答案并没有帮助。我该如何使jOOQ存储正确的时间戳?


你可以为你的客户端设置时区为UTC,或者使用显式转换cast($2 as timestamptz) - Vao Tsun
JDBC规范要求在JVM默认时区发送时间戳,除非:1)通过传递具有正确时区的“日历”来明确指定;2)插入到具有特定时区的列中;3)使用“java.time.OffsetDateTime”。 - Mark Rotteveel
我注意到您还没有接受任何答案。请考虑在某个时候这样做。 - GhostCat
1个回答

1

Timestamp类本身对时区一无所知。

换句话说:它假设传入的值是UTC时间。

但是,当Timestamp进一步处理时(且没有特别设置),从Timestamp对象“检索”的值并推送到数据库中的值将考虑您当前的语言环境。

您可以在这里查看更多想法。 Mikael Valot的答案提供了一些示例,说明如何检索要传递给TimeStamp构造函数的值以涉及时区。


1
好的,那么我该如何告诉jOOQ(假设它是罪魁祸首)不要将Timestamp翻译成我的当前语言环境? - Tomáš M.
@TomášM。请参见https://blog.jooq.org/tag/time-zones/和https://dev59.com/-Ybca4cB1Zd3GeqPa9e7。 - Mark Rotteveel
1
@TomášM.:这与 jOOQ 无关(它只是将 Timestamp 传递给 JDBC),而是一个 JDBC / PostgreSQL 问题。您可能希望使用 timestamp with time zone 作为 PostgreSQL 数据类型,并在 jOOQ 中应用正确的数据类型绑定,将其映射到 java.time.OffsetDateTime - Lukas Eder
非常感谢Lukas,问题确实得到解决了。 - Tomáš M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接