且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

jOOQ时间戳与本地时区偏移量一起存储

更新时间:2021-07-15 15:07:30

不幸的是,您遇到了一些不利于您的事情:

Unfortunately you have a few things working against you:

  1. PostgreSQL JDBC驱动程序在Postgres会话中将时区设置为您的JVM时区.因此,即使您的数据库服务器以UTC运行,也会使用JVM的时区插入TIMESTAMP字段.当您插入或查询数据时,数据库服务器将始终使用JVM时区.
  2. 您使用的是TIMESTAMP而不是TIMESTAMPTZ.这些类型的描述未反映其实际用法. TIMESTAMPTZ实际上意味着时区不可知.无论您插入什么值,都将使用会话时区将其调整为UTC.

由于这两个问题,如果您有两个不同的JVM(一个使用洛杉矶时间,另一个使用纽约时间),则每当您使用一个JVM编写TIMESTAMP时,它就会是不同的"UTC时间"其他JVM. TIMESTAMP使用调整后的值,并按给定方式使用它.如果将TIMESTAMP列更改为TIMESTAMPTZ,则两个JVM中的相同时间将始终是相同的UTC时间.

Because of these two issues, if you have two different JVMs -- one using Los Angeles time and the other using New York time -- whenever you write a TIMESTAMP with one JVM it will be a different "UTC time" in the other JVM. TIMESTAMP takes the adjusted value and just uses it as given. If you change your TIMESTAMP columns to be TIMESTAMPTZ then the same time in both JVMs will always be the same UTC time.

如果查看Postgres JDBC驱动程序的ConnectionFactoryImpl#openConnectionImp,您会看到它在哪里将本地JVM的时区设置为数据库服务器会话区的时区.

If you look at the Postgres JDBC Driver's ConnectionFactoryImpl#openConnectionImp you can see where it sets your local JVM's time zone as the time zone for the database server's session zone.

因此,解决此问题的唯一明智的方法是仅使用TIMESTAMPTZ而不是TIMESTAMP.这是有关此的更多信息:

So the only sane way to deal with this is to only ever use TIMESTAMPTZ instead of TIMESTAMP. Here's some more information on this:

PostgreSQL/JDBC和TIMESTAMP与TIMESTAMPTZ的对比

http://justatheory.com/computers/databases/postgresql/use -timestamptz.html