加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – Postgres数据库中奇特的时区处理

发布时间:2020-12-13 16:09:16 所属栏目:百科 来源:网络整理
导读:我的环境 我在法国巴黎(UTC 1或CET). 现在是凌晨12点(00:00),我们是2016年11月25日. 我的Postgres数据库托管在eu-west-1地区的Amazon Web Services(AWS RDS)上. 问题 查询具有特定时区集的current_date(或current_time)似乎会产生与我的信念不一致的结果. 特
我的环境

我在法国巴黎(UTC 1或CET).
现在是凌晨12点(00:00),我们是2016年11月25日.
我的Postgres数据库托管在eu-west-1地区的Amazon Web Services(AWS RDS)上.

问题

查询具有特定时区集的current_date(或current_time)似乎会产生与我的信念不一致的结果.

特别是,在使用CET时区或UTC 1时,查询current_date会产生不同的结果.

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是否在此中发挥作用?

解决方法

这个问题似乎与Amazon RDS无关:它与PostgreSQL使用的约定有关.在这种情况下,您确实有向后的时区名称.你的意思是’UTC-01′,你写’UTC 01′.
从 the manual开始:

Another issue to keep in mind is that in POSIX time zone names,
positive offsets are used for locations west of Greenwich. Everywhere
else,PostgreSQL follows the ISO-8601 convention that positive
timezone offsets are east of Greenwich.

因此,用于SET TIME ZONE的时区字符串(以及相应的SHOW时区的显示)或AT TIME ZONE构造使用与时间戳(带时区)文字中显示的相反的符号!这是ISO和SQL标准与POSIX之间非常不幸的分歧. (我认为POSIX应该受到指责.)参见:

> Oddities with AT TIME ZONE and UTC offsets
> Why does PostgreSQL interpret numeric UTC offset as POSIX and not ISO-8601?

但是’CET’或’UTC-01’对于巴黎来说仍然可能是错误的,因为他们没有考虑夏令时的规则.
(夏令时是人类历史上最愚蠢的概念之一.)

巴黎(与欧洲大部分地区一样)在冬季使用CET,在夏季使用CEST.你在’CET’的考试恰好在11月开始.如果你在夏天尝试相同,你会得到错误的结果.

为了安全起见,请始终使用考虑DST规则的时区名称“Europe / Paris”.电话费用更贵.

如果您的时区设置意味着任何时间,则函数current_time会考虑DST规则.但是’UTC-01’是一个普通的时间偏移.我从不使用带有时区或current_time的数据类型时间.手册再次:

We do not recommend using the type time with time zone (though it is
supported by PostgreSQL for legacy applications and for compliance
with the SQL standard)

考虑:

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

06001

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!

06003

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

06005

有关:

> Ignoring time zones altogether in Rails and PostgreSQL
> Time zone names with identical properties yield different result when applied to timestamp
> Time zone storage in data type “timestamp with time zone”

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读