PostgreSQL:将字符串转换为没有时区的时间戳以更改时间日期时,我得到了意想不到的结果

Posted

技术标签:

【中文标题】PostgreSQL:将字符串转换为没有时区的时间戳以更改时间日期时,我得到了意想不到的结果【英文标题】:PosgreSQL: I get unexpected results when casting strings as timestamp without time zone for changing time date 【发布时间】:2021-12-08 23:54:23 【问题描述】:

服务器信息

显示时区;

欧洲/巴黎

我曾经在没有时区的时间戳中转换字符串:

选择'2003-04-30 02:01:47'::时间戳

2003-04-30 02:01:47

通常 CAST 效果很好,但我最近发现 PostgreSQL 在某些特定情况下不会呈现预期值。事实上,对于法国的每个夏季时间变化日以及凌晨 2 点到 3 点之间的时间,PostgreSQL 看起来都希望将字符串更改为本地时间,而不是 UTC,就像其他日期一样!!

选择'2003-03-30 02:01:47'::时间戳

2003-03-30 03:01:47

任何解释以及如何按预期获取时间戳(不更改服务器配置)?

【问题讨论】:

确实很奇怪,但在我的情况下仅适用于带有时区的时间戳:SELECT '2003-03-30 02:59:59'::timestamp with time zone 在我的情况下 SELECT '2003-03-30 02:59:59'::timestamp 和 SELECT '2003-03-30 02:59:59'::timestamptz 返回相同的结果 > 2003 -03-30 03:59:59,这就是重点!! 我无法重现。什么版本? PostgreSQL 12.8 on x86_64-pc-linux-gnu,由 gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1) 编译,64 位 【参考方案1】:

在没有时区的时间戳的情况下,我无法解释你的行为,因为这不会发生在我这边。

在带时区的时间戳的情况下,情况更复杂:在 02:00:00 和 02:59:59 之间,系统将字符串转换为时间戳,同时将偏移量增加 1,因为从冬季切换时间到夏令时并将时间增加 1 小时,因为 02:00:00+01(冬令时)= 03:00:00+02(夏令时)。

问题在于,在 03:00:00,转换不再将时间增加 1,以实现我们因切换而损失 1 小时的事实。

因此,字符串 '03:00:00' 被转换为时间戳 '03:00:00+02',它比时间戳 '03:59:59+02' 早 59 分 59 秒转换为字符串“02:59:59”。从时间线的角度来看,字符串“03:00:00”和“02:59:59”的转换不一致。

我在这一点上提出了一个错误,建议禁止在“2003-03-30 02:00:00”和“2003-03-30 02:59:59”之间转换字符串,并明确指出由于冬令时/夏令时切换,相应的时间间隔从未存在过。

Here 是来自 Tom Lane 的错误报告

Here是相关文档

【讨论】:

【参考方案2】:

好的,这个问题与 Postgresql 无关。我使用 dbeaver 作为客户端与 Posgresql 进行通信。为了解决这个问题,我必须在 dbeaver 选项中禁用数据/时间格式:

看看这个issue。

特别是这个comment。

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于PostgreSQL:将字符串转换为没有时区的时间戳以更改时间日期时,我得到了意想不到的结果的主要内容,如果未能解决你的问题,请参考以下文章

PostgresQL + Spring JPA:org.postgresql.util.PSQLException:错误:无法将类型 bytea 转换为没有时区的时间戳

将 postgresql 中的 UTC 时区转换为 EST(本地时间)

Postgresql 在没有时区的情况下将秒转换为时间

PostgreSQL 错误地从没有时区的时间戳转换为有时区的时间戳

如何将日期字符串转换为没有时区的日期对象

python - 如何在没有dateutil的情况下将时区感知字符串转换为Python中的日期时间?