postgresql 不正确的时区从夏令时更改

Posted

技术标签:

【中文标题】postgresql 不正确的时区从夏令时更改【英文标题】:postgresql incorrect timezone change from summer time 【发布时间】:2013-11-17 12:54:08 【问题描述】:

我在安装了 Postgresql 的 CentOS 6.x 上运行系统:

x86_64-unknown-linux-gnu 上的 PostgreSQL 9.0.11,由 GCC gcc (GCC) 4.1.2 编译 20080704(红帽 4.1.2-52),64 位

我现在面临的问题如下:

PostgreSQL 配置:

\#timezone = unknown # 实际上,默认为 TZ 环境

来自 psql 的会话配置:

select setting 
from pg_settings 
where name in ('TimeZone', 'timezone_abbreviations');

Israel
Default
---- - 操作系统时区是以色列: zdump -v /etc/localtime |grep 2013 /etc/localtime 2013 年 3 月 28 日星期四 23:59:59 UTC = 2013 年 3 月 29 日星期五 01:59:59 IST isdst=0 gmtoff=7200 /etc/localtime 2013 年 3 月 29 日星期五 00:00:00 UTC = 2013 年 3 月 29 日星期五 03:00:00 IDT isdst=1 gmtoff=10800 /etc/localtime 2013 年 10 月 26 日星期六 22:59:59 UTC = 2013 年 10 月 27 日星期日 01:59:59 IDT isdst=1 gmtoff=10800 /etc/localtime 2013 年 10 月 26 日星期六 23:00:00 UTC = 2013 年 10 月 27 日星期日 01:00:00 IST isdst=0 gmtoff=7200 ----

现在 - 根据 zdump 从夏季时区的转换应在 10 月 27 日星期日 01:00:00 完成。 当我跑步时

select '2013-09-06 00:00:00'::timestamptz it shows date in +03 timezone - 2013-09-06 00:00:00+03

但是当我运行时

select '2013-09-08 00:00:00'::timestamptz 它在 +02 时区显示日期 - 2013-09-06 00:00:00+02 但它应该在 +03 中显示它,因为时区偏移只会在 2013-09-06 00:00:00'::timestamptz 10 月 27 日星期日 01:00:00。

所以有2个问题

    postgresql 如何保持时区转换的日期以及如何检查当前值。 我该如何解决这个问题。

【问题讨论】:

【参考方案1】:

Postgres 源包含/src/timezone/data 中的 TZDB 副本。随着 Postgres 新版本的发布,它会定期更新。

根据the revision history,撰写本文时的最新版本是2013d。这确实是包含您正在寻找的以色列更改的版本。请参阅2013d release announcement。因此,如果您可以更新您的 Postgres 版本,您应该会看到您正在寻找的更改。

查看发布日期,该数据似乎应该在以下任何版本中:

9.3.1
9.3
9.2.5
9.1.10
9.0.14
8.4.18

您说您运行的是 9.0.11,其发布日期为 2012-12-06,因此您当前使用的是 TZDB 版本 2012j。这解释了您描述的时间戳的差异。您应该至少将 Postgres 更新到 9.0.14 版本。

但是,由于您在 Linux 系统上运行,并使用它自己的 tzdata 副本,您可以采用不同的方法并告诉 Postgres 使用 那个 数据而不是它自己的数据。从源代码构建 postgres 时,您必须向 configure 提供参数。

来自the documentation here:

--with-system-tzdata=DIRECTORY

PostgreSQL 包含自己的时区数据库,它需要日期和时间操作。这个时区数据库实际上是兼容FreeBSD、Linux、Solaris等很多操作系统提供的“zoneinfo”时区数据库,所以重新安装就显得多余了。使用此选项时,将使用 DIRECTORY 中系统提供的时区数据库,而不是 PostgreSQL 源代码分发中包含的那个。 DIRECTORY 必须指定为绝对路径。 /usr/share/zoneinfo 可能是某些操作系统上的目录。请注意,安装例程不会检测不匹配或错误的时区数据。如果您使用此选项,建议您运行回归测试以验证您所指向的时区数据在 PostgreSQL 中是否正常工作。

此选项主要针对熟悉目标操作系统的二进制包分发者。使用此选项的主要优点是,只要许多本地夏令时规则中的任何一个发生更改,就不需要升级 PostgreSQL 包。另一个优点是,如果安装时不需要构建时区数据库文件,PostgreSQL 可以更直接地进行交叉编译。

【讨论】:

请注意,仅仅因为 OP 在 Linux 上运行并不意味着从源代码构建诸如 Postgres 之类的大型项目是微不足道的。是否可以将操作系统的(或下载的)tzdata 复制/符号链接到 Postgres 已经在查找的目录中? 我不是 postgres 专家,但我认为不是。除非您使用该标志进行编译,否则它可能根本不会在运行时读取文件。不过我可能是错的。可能最简单的做法是下载 9.0.14 版的更新。

以上是关于postgresql 不正确的时区从夏令时更改的主要内容,如果未能解决你的问题,请参考以下文章

没有时区的时间戳中的夏令时时间偏移

测试正确的时区处理

PostgreSQL 中的本地时区偏移量

如何在android中处理时区和夏令时?

PostgreSQL:在不同时区的时间戳中添加间隔

双重检查 PostgreSQL 服务器上的夏令时规则是最新的吗?