最近埃及更改了 DST 规则,我在使用 Postgres 时遇到了问题,因为函数 now()
返回了错误的时区。
我的时区是非洲/开罗,现在是+3:00
,但 Postgres 返回+2:00
select now();
返回:
2023-05-05 22:17:06.461 +0200
应该是:
2023-05-05 23:17:06.461 +0300
我的 Postgres 是容器化的。
主办方时间:2023 年东部夏令时间 5 月 5 日星期五 23:19:26
(正确)。
Postgres 容器中的时间:Fri 05 May 2023 11:22:00 PM EEST
(正确)。
timezone
配置正确:
show timezone; -- returns Africa/Cairo
“非洲/开罗”的时区
表条目为+3:00:
select * from pg_timezone_names
where name = 'Africa/Cairo';`
返回:
Africa/Cairo EEST 03:00:00 true
Postgres 版本:
PostgreSQL 15.2 (Debian 15.2-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
我不知道为什么 now() 没有按预期工作。
最佳答案
the function
now()
is returning the wrong timezone.
严格来说,函数now()
(又名transaction_timestamp()
或CURRENT_TIMESTAMP
)根本不“返回时区” 。从 now()
返回的 timestamptz
的显示由调用 session 的当前时区
设置控制 -反过来,遵循 IANA timezone database 中规定的规则.
公平地说,埃及政府在很短的时间内就重新引入了夏令时。 According to Wikipedia:
On 1 March 2023, the Egyptian Cabinet passed law 24 of 2023 to reinstate DST, moving to UTC+03:00 starting from the last Friday of April (28 April) at 00:01 until the last Thursday of October (26 October) at 23:59.
令我感到困惑的是,任何国家都会恢复夏令时规则。世界应该尽快摆脱这种有害的废话!
Postgres 要么使用自己的副本,要么(更常见)底层操作系统的时区数据库(如果它是使用选项 --with-system-tzdata=DIRECTORY
编译的)。
我的本地安装就是这种情况。我发现pg_config --configure
。我的 Postgres 15.2 已使用选项 --with-system-tzdata=/usr/share/zoneinfo
进行编译。
由于我的操作系统是最新的,并且从 4 月中旬开始对 /usr/share/zoneinfo/Africa/Cairo
进行了更新,因此我安装的所有 Postgres 版本也是如此。我得到“非洲/开罗”的夏季时间,2023 年的偏移量为 +03:00(但不是 2022 年)。
我可以在 dbfiddle.uk 上重现您的问题,但它还不是最新的:
(这可能随时改变。)
唯一令人费解的细节是,您在 pg_timezone_names
中看到了正确的条目,就像我在本地所做的那样,但与 fiddle 不同。 (?)
为什么它对你不起作用?
我可以看到三个可能的原因:
您的 Postgres 版本不是使用
--with-system-tzdata=DIRECTORY
编译的。 Postgres 15.2 于 2023 年 2 月 9 日发布,目前还没有最新的 IANA 补丁。 (我希望下一个版本能够包含更新。)您的 Postgres 版本是使用
--with-system-tzdata=DIRECTORY
编译的, 但您没有安装操作系统更新(就像您应该的那样)。由于容器化安装,翻译过程中丢失了一些内容。
相关:
关于postgresql - Postgres 函数 now() 返回不正确的时区偏移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76185736/