postgresql - Postgres 数据库中特殊的时区处理

标签 postgresql amazon-web-services timezone

我的环境

我在法国巴黎(UTC+1CET)。
这是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 |
+---------------------------------+

Nope, that was yesterday -- two hours ago.


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+1UTC-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 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 zonecurrent_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
     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

相关:

关于postgresql - Postgres 数据库中特殊的时区处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40795645/

相关文章:

database - Jhipster 和 Postgres 连接

php - Postgres - 如何从表中获取转义数据

amazon-web-services - 从本地 Spark 访问 AWS Glue

java - AWS S3 - com.amazonaws.AmazonServiceException : Request ARN is invalid

jquery - 获取时区名称

python - 获取LMT信息以及pytz中的所有缩写tz

python - 海量数据集的Django轻量级 "update"

sql - 如果一行存在,Postgres 加入并返回标志

amazon-web-services - 根据之前在参数 CloudFormation 上选择的值更改分配的参数值

django - 不带过滤器的输出时区感知 django 日期时间字段