为什么即使没有时区偏移量,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 InterpretationHandling of Invalid or Ambiguous Timestamps,都无济于事)。

解决方法

因为您的 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)