postgresql timezone conversion'EST'!=' - 05'

问题描述 投票:2回答:2

我在x86_64-pc-linux-gnu上运行PostgreSQL 9.6.6,我的时区设置为'UTC'。

有谁知道为什么以下SELECT声明的结果不同?

一个)

SELECT timezone('EST', '2017-12-21');
    timezone       
---------------------
2017-12-20 19:00:00

B)

SELECT timezone('-05', '2017-12-21');
      timezone       
---------------------
2017-12-21 05:00:00

根据pg_timezone_names-05应该与EST具有相同的偏移...任何想法?谢谢。

sql postgresql postgresql-9.6
2个回答
2
投票

https://www.postgresql.org/docs/current/static/view-pg-timezone-names.html

视图pg_timezone_names提供SET TIMEZONE识别的时区名称列表

并进一步:

utc_offset interval UTC的偏移量(正值表示格林威治以东)

当你set timezone to 'EST' - 你声明你的客户在EST时区,因此返回的时间将根据你的tz进行调整:

t=# select '2017-12-21'::timestamptz;
      timestamptz
------------------------
 2017-12-21 00:00:00-05
(1 row)

区间匹配来自pg_timezone_names和isequal -05的utc_offset,因此它按预期工作。 (如果你set timezone to '-05',确实在EST将比UTC少5小时)相同的结果。

-05EST都给出了SET TIMEZONE的相同结果,如文档中所述。

现在,您使用intervalhttps://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT回答与文档的协调

在这些表达式中,期望的时区区域可以指定为文本字符串(例如,“PST”)或指定为间隔(例如,INTERVAL'-08:00')。

遵循这些规则也可以:

t=# select '2017-12-21'::timestamptz at time zone 'EST';
      timezone
---------------------
 2017-12-20 19:00:00
(1 row)

t=# select '2017-12-21'::timestamptz at time zone interval '-05:00';
      timezone
---------------------
 2017-12-20 19:00:00
(1 row)

但是,文档说:

在文本案例中,可以使用第8.5.3节中描述的任何方式指定时区名称。

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

PostgreSQL允许您以三种不同的形式指定时区:

  • 识别的时区名称列在pg_timezone_names中
  • 公认的缩写列在pg_timezone_abbrevs中
  • 形式为STDoffset或STDoffsetDST的POSIX风格时区规范

(格式化我的)

最后:

人们应该警惕POSIX风格的时区功能可以导致默默地接受虚假输入...另外要记住的一个问题是,在POSIX时区名称中,正偏移用于格林威治以西的位置。在其他地方,PostgreSQL遵循ISO-8601惯例,正面时区偏移位于格林威治以东。

TL; DR

所以简而言之 - 当你为timezone()函数或AT TIME ZONE指令定义'-05'作为文本(不是间隔)输入时(实际上相同)Postgres认为这是尝试使用POSIX样式时区并因此反转符号,因此你得到“对面“结果......

这个记录的反演的简单演示:

t=# select '2017-12-21'::timestamptz at time zone '05';
      timezone
---------------------
 2017-12-20 19:00:00
(1 row)

1
投票

好吧,我想我找到了自己问题的答案:

根据PostgreSQL文档,第9.9.3节在以下链接https://www.postgresql.org/docs/9.6/static/functions-datetime.html

在这些表达式中,期望的时区区域可以指定为文本字符串(例如,“PST”)或指定为间隔(例如,INTERVAL'-08:00')。在文本案例中,可以使用第8.5.3节中描述的任何方式指定时区名称。

因此,使用INTERVAL语法,以下似乎工作:

SELECT timezone(INTERVAL '-05:00', '2017-12-21');
      timezone       
---------------------
2017-12-20 19:00:00

我认为它仍然很奇怪,SELECT timezone('-05', '2017-12-21');究竟意味着什么,因为以下内容也提供了预期的结果(添加了TZ偏移量):

SELECT timezone('-05', '2017-12-21'::timestamp);
        timezone        
------------------------
2017-12-20 19:00:00+00
© www.soinside.com 2019 - 2024. All rights reserved.