首页 > 解决方案 > 为什么即使没有时区偏移,PostgreSQL 也会将带有时间戳的字符串强制转换为“TIMESTAMP WITH TIME ZONE”?

问题描述

我在 PostgreSQL v11.10 上,并且TimeZone设置为UTC.

当我说select '2021-02-16 17:45+00' at time zone 'America/New_York';,我得到2021-02-16 12:45:00,这是正确和预期的。

但是,当我说 时select '2021-02-16 17:45' at time zone 'America/New_York';,我得到了相同的结果。

似乎两个字符串都被强制转换为timestamp with time zone,对于后一个字符串,这对我来说似乎有点违反直觉。为什么 PostgreSQL 会这样?它是否记录在手册中(我查看了以下位置:AT TIME ZONE,然后是Date/Time Types以及Date/Time Input Interpretation and Handling of Invalid or Ambiguous Timestamps,都无济于事)。

标签: postgresqldatetimetimezone

解决方案


因为您TimeZone设置为UTC,所以没有指定时区的任何时间戳都将被解释为 UTC 时区的本地时间。由于您要求将时间戳解释为America/New_York,因此 Postgres 将首先将时间戳解释为 UTC 时间戳,然后进行数学运算将其转换为America/New_York.

请注意,如果您实际查看发送到 Postgres 的类型,timestamp with timezone除非您指定它,否则它不会强制转换:

edb=# select pg_typeof('2021-02-16 17:45' at time zone 'America/New_York');
          pg_typeof          
-----------------------------
 timestamp without time zone
(1 row)

edb=# select pg_typeof('2021-02-16 17:45+00' at time zone 'America/New_York');
          pg_typeof          
-----------------------------
 timestamp without time zone
(1 row)

edb=# select pg_typeof('2021-02-16 17:45+00'::timestamptz at time zone 'America/New_York');
          pg_typeof          
-----------------------------
 timestamp without time zone
(1 row)

edb=# select pg_typeof('2021-02-16 17:45+00'::timestamptz);
        pg_typeof         
--------------------------
 timestamp with time zone
(1 row)

edb=# select pg_typeof('2021-02-16 17:45+00'::timestamp);
          pg_typeof          
-----------------------------
 timestamp without time zone
(1 row)

推荐阅读