PostgreSQL 9.3 / postgresql-9.3-1100-jdbc41.jar
我有一个类型为timezone without time zone
的列的表,这会生成具有适用的java.util.Timestamp
属性的Object。
我在插入过程中看到的是jOOQ绑定过程将java.util.Timestamp
转换为具有本地时区偏移的日期。
例如,对于unix时间戳1421109419(2015年1月13日00:36:59 GMT),该属性设置为new Timestamp(1421109419 * 1000)
。
2015-01-13 14:14:31,482 DEBUG [http-bio-8002-exec-4] org.jooq.tools.LoggerListener#debug:255 - -> with bind values : insert into "foo"."bar" ("start_date") values (timestamp '2015-01-13 13:36:59.0') returning "foo"."bar"."id"
2015-01-13 14:14:31,483 TRACE [http-bio-8002-exec-4] org.jooq.impl.DefaultBinding#trace:179 - Binding variable 3 : 2015-01-13 13:36:59.0 (class java.sql.Timestamp)
并且在记录中肯定是价值" 2015-01-13 13:36:59"。
该软件在NZDT的机器上运行,解释了+13偏移量。
鉴于TimeZone不可知容器(Timestamp)中提供的时间,我希望在创建insert语句时能够得到尊重。
如何让jOOQ创建时间戳不是在当地时间?
答案 0 :(得分:5)
不幸的是,你有一些事情不利于你:
由于这两个问题,如果您有两个不同的JVM - 一个使用洛杉矶时间而另一个使用纽约时间 - 每当您使用一个JVM编写TIMESTAMP时,它将是一个不同的" UTC时间& #34;在另一个JVM中。 TIMESTAMP获取调整后的值,并按指定使用它。如果将TIMESTAMP列更改为TIMESTAMPTZ,则两个JVM中的相同时间将始终为相同的UTC时间。
如果查看Postgres JDBC驱动程序的ConnectionFactoryImpl#openConnectionImp,您可以看到它将本地JVM的时区设置为数据库服务器会话区的时区。
所以解决这个问题的唯一理智方法是只使用TIMESTAMPTZ代替TIMESTAMP。以下是有关此内容的更多信息:
PostgreSQL/JDBC and TIMESTAMP vs. TIMESTAMPTZ
http://justatheory.com/computers/databases/postgresql/use-timestamptz.html
答案 1 :(得分:0)
以下(非常讨厌的)代码对我有用:
eventsRecord.setCreatedOn(new Timestamp(System.currentTimeMillis()
- TimeZone.getDefault().getOffset(new Date().getTime())));
Alas jOOQ在保存到PostgreSQL时只使用本地时区"时区没有时区"或MySQL" datetime"领域。此次歪曲的源代码证据是here,它没有指定时区,也没有任何设施供用户覆盖此功能并指定时区。这使得来自jOOQ的这种非常基本的数据类型的使用完全无用,大量客户端都使用不同的时区将数据写入同一字段而不记录其时区,也不将数据规范化为UTC。
JDBC提供了额外的three-argument setTimestamp,用户可以在其中指定所需的时区(UTC基本上是唯一有意义的值)。然而,jOOQ"摘要"远离JDBC并且不提供此功能。