Postgres UTC时间戳?

时间:2017-05-26 11:00:49

标签: sql postgresql timestamp

我想在几个表中使用UTC时间戳“创建”字段。

ts TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),给了我带时区的当地时间:

foo=# select ts from messages;
              ts               
-------------------------------
 2017-05-26 11:54:07.532796+01
 2017-05-26 11:54:08.536241+01
 2017-05-26 11:54:09.538119+01
 2017-05-26 11:54:10.541089+01
 2017-05-26 11:54:11.543262+01

ts TIMESTAMP NOT NULL DEFAULT now(),给我当地时间没有时区信息(危险):

foo=# select ts from messages;
             ts             
----------------------------
 2017-05-26 11:56:00.134596
 2017-05-26 11:56:01.13798
 2017-05-26 11:56:02.140586
 2017-05-26 11:56:03.143076
 2017-05-26 11:56:04.14565

当代码在非UTC时区的服务器上运行时(例如BST,英国夏令时),什么字段定义会给我以下内容:

foo=# select ts from messages;
             ts             
----------------------------
 2017-05-26 10:56:00.134596+00
 2017-05-26 10:56:01.13798+00
 2017-05-26 10:56:02.140586+00
 2017-05-26 10:56:03.143076+00
 2017-05-26 10:56:04.14565+00

甚至:

foo=# select ts from messages;
             ts             
----------------------------
 2017-05-26 10:56:00.134596
 2017-05-26 10:56:01.13798
 2017-05-26 10:56:02.140586
 2017-05-26 10:56:03.143076
 2017-05-26 10:56:04.14565
如果没有别的办法可以,那么

就没问题了(注意:时间是UTC时间上午10点,而不是上面两个例子中的BST上午11点)。

1 个答案:

答案 0 :(得分:2)

时区的时间戳是您的选择:

t=# select now();
              now
-------------------------------
 2017-05-26 11:04:19.240294+00
(1 row)

t=# set timezone to 'EET';
SET
t=# select now();
              now
-------------------------------
 2017-05-26 14:04:45.749123+03
(1 row)

但如果您插入select now(),它将节省UTC时间,您可以检查:

t=# select now() at time zone 'utc';
          timezone
----------------------------
 2017-05-26 11:05:01.045544
(1 row)

https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-TIMEZONES

  

所有时区感知日期和时间都以UTC格式存储在内部。他们   将在TimeZone指定的区域中转换为本地时间   配置参数在显示给客户端之前。