如何将普遍协调的时间插入PostgreSQL TIMESTAMP列?

时间:2017-06-13 19:03:50

标签: postgresql timestamp

我的数据库和客户端目前在America / New_York,但可以移动到任何地方。

SHOW TIMEZONE; -- America/New_York

CREATE TABLE times (
  t TIMESTAMP WITHOUT TIME ZONE
);

INSERT INTO times VALUES
  (NOW()),
  (NOW() AT TIME ZONE 'UTC');

SELECT t FROM times;
-- 2017-06-13 14:53:17.766969
-- 2017-06-13 18:53:17.766969

这是出乎意料的。我以为我的SELECT会为两个记录返回相同的值。

当我将当前时间插入列t时,我希望它表示任何时区的当前时间(数据库是否将基础值存储为当前时间UTC)。这样,无论数据库运行的时区,还是客户端运行的时区,每个人都可以就普遍协调的固定时间点达成一致。

INSERT记录的正确方法是什么,以便世界上的每个人都知道我引用了'UTC'时间?

1 个答案:

答案 0 :(得分:0)

首先,似乎SELECT假定没有时区字段的时间戳存储在本地时区。试试SET TIME ZONE 'UTC+<n>SELECT的输出不会改变(即,如果没有存储时区,它就不像时间戳意味着UTC!)

如果字段timestamp with time zoneSELECT正确地将输出转换为当前时区。

所以当你说AT TIME ZONE 'UTC'你把时间转换成UTC时,就丢弃时区让Postgres认为你正在处理当地时间。

您可以通过添加另一个AT TIME ZONE 'UTC'子句重新引入UTC时区:

# select pg_typeof(now() at time zone 'utc');
timestamp without time zone

# select pg_typeof(now() at time zone 'utc' at time zone 'utc'); 
timestamp with time zone

结论:如果您坚持不使用时区,我会始终使用TIME WITH TIME ZONE或始终将数据库时区设置为UTC。两种类型的存储大小似乎相同(64位)。