微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我的环境

我在法国巴黎(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”

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐