我在巴黎,法国(UTC+1
或CET
)。
它是12am
(00:00
),我们在 2016年11月25日。
我的 Postgres 数据库托管在eu-west-1
区域的 Amazon Web Services (AWS RDS)上。
查询具有特定时区设置的current_date
(或current_time
)似乎可以提供与......我的信念不一致的结果。
特别是,在使用current_date
时区或CET
时,查询UTC+1
会产生不同的结果。
SET TIME ZONE 'UTC+01';
select current_date, current_time;
+------------+--------------------+ | date | timetz | +------------+--------------------+ | 2016-11-24 | 22:00:01.581552-01 | +---------------------------------+
不,那是昨天 - 两个小时前。
SET TIME ZONE 'CET';
select current_date, current_time;
或
SET TIME ZONE 'Europe/Paris';
select current_date, current_time;
+------------+--------------------+ | date | timetz | +------------+--------------------+ | 2016-11-25 | 00:00:01.581552-01 | +---------------------------------+
有正确的时间和日期。
那里发生了什么?
对我来说为时已晚,我混淆了UTC+1
和UTC-1
还是有更大的东西让我俯视?
AWS RDS是否在此中发挥作用?
答案 0 :(得分:2)
这个问题似乎与Amazon RDS无关:它与PostgreSQL使用的约定有关。在这种情况下,您执行后退时区名称。你的意思是 'UTC-01'
,你写的是 。'UTC+01'
来自the manual:
要记住的另一个问题是在POSIX时区名称中, 正偏移用于格林威治的 west 位置。到处 否则,PostgreSQL遵循ISO-8601惯例,即积极的 时区偏移是格林威治的东。
因此,用于SET TIME ZONE
的时区字符串(以及相应的SHOW timezone
的显示)或AT TIME ZONE
构造使用相反符号显示的内容timestamp
(with time zone
)文字!这是ISO和SQL标准与POSIX之间非常不幸的分歧。 (我认为POSIX应该受到指责。)见:
但巴黎的 'CET'
或'UTC-01'
仍可能存在错误,因为他们没有考虑夏令时的规则。<登记/>
(DST是人类历史上最愚蠢的概念之一。)
巴黎(与欧洲大部分地区一样)在冬季使用CET,在夏季使用CEST。您'CET'
的测试恰好在11月开始工作。如果您在夏天尝试相同的操作,则会得到错误的结果。
为安全起见,请始终使用考虑DST规则的时区名称 'Europe/Paris'
。电话费用更高。
如果您的时区设置意味着任何,则函数current_time
会将DST规则考虑在内。但'UTC-01'
是一个明确的时间偏移。我从不使用数据类型time with time zone
或current_time
开头。手册再次出现:
我们不建议使用
time with time zone
类型(虽然它是 PostgreSQL支持遗留应用程序和合规性 使用SQL标准)
考虑:
SELECT '2016-06-06 00:00+0'::timestamptz AT TIME ZONE 'UTC+01' AS plus_wrong
, '2016-06-06 00:00+0'::timestamptz AT TIME ZONE 'UTC-01' AS minus_right
plus_wrong | minus_right ---------------------+--------------------- 2016-06-05 23:00:00 | 2016-06-06 01:00:00
SELECT '2016-01-01 00:00+0'::timestamptz AT TIME ZONE 'CET' AS cet_winter
, '2016-06-06 00:00+0'::timestamptz AT TIME ZONE 'CEST' AS cest_summer
, '2016-06-06 00:00+0'::timestamptz AT TIME ZONE 'CET' AS cet_no_dst -- CET wrong!
cet_winter | cest_summer | cet_no_dst ---------------------+---------------------+--------------------- 2016-01-01 01:00:00 | 2016-06-06 02:00:00 | 2016-06-06 01:00:00 -- wrong
SELECT '2016-06-06 00:00+0'::timestamptz AT TIME ZONE 'Europe/Paris' AS paris_summer
, '2016-01-01 00:00+0'::timestamptz AT TIME ZONE 'Europe/Paris' AS paris_winter
paris_summer | paris_winter ----------------------+---------------------- 2016-06-06 02:00:00 | 2016-01-01 01:00:00 -- always right
相关: