PostgreSQL 时区与系统时区不匹配

PostgreSQL 时区与系统时区不匹配

我有几个 PostgreSQL 9.2 安装,其中 PostgreSQL 使用的时区是 GMT,尽管整个系统是“欧洲/维也纳”。我仔细检查了一下,postgresql.conf确实不是包含timezone设置,因此根据文档它应该回退到系统的时区。

然而,

# su -s /bin/bash postgres -c "psql mydb"

mydb=# show timezone;
 TimeZone 
----------
 GMT
(1 row)

mydb=# select now();
              now              
-------------------------------
 2013-11-12 08:14:21.697622+00
(1 row)

有什么提示吗?GMT 时区可能来自哪里?系统用户没有TZ设置,并且/etc/timezone似乎/etc/timeinfo配置正确。

# cat /etc/timezone 
Europe/Vienna
# date
Tue Nov 12 09:15:42 CET 2013

如有任何提示,我们将不胜感激,提前致谢!

答案1

该设置的默认值TimeZone已在 9.2 版中发生更改:

(..)如果未明确设置,服务器会将此变量初始化为其系统环境指定的时区。(...)

(...) 内置默认值为 GMT,但通常在 postgresql.conf 中被覆盖;initdb 将在那里安装与其系统环境相对应的设置。(...)

这意味着在 9.2 版之前,默认值postgresql.conf应在initdb阶段期间设置。如果您覆盖该值(可能在从旧版本升级时复制旧值postgresql.conf),PostgreSQL 将使用“GMT”值作为默认值。

您的案例的解决方案非常简单,只需将TimeZone设置更改postgresql.conf为您想要的值即可:

TimeZone = 'Europe/Vienna'

之后您需要reload服务:

# su - postgres -c "psql mydb -c 'SELECT pg_reload_conf()'"

然后从现在起,所有存储为timestamp with time zone(或timestamptz) 的字段都将正确显示。但您必须手动更正(更新)所有存储为timestamp without time zone(或timestamp) 的字段。

我给所有升级 PostgreSQL 的人的一个提示是不要将旧版本复制postgresql.conf到新集群(请注意,我不确定你是否这样做了,但我因此经常看到同样的问题)。只需获取生成的版本initdb并添加修改即可(diff工具可能难以完成此任务)。

答案2

我找到了解决这个问题的方法。

只需在里面创建一个符号链接/usr/share/zoneinfo/命名当地时间(或任何您希望的名字)指向/etc/本地时间

/usr/share/zoneinfo/localtime -> /etc/localtime

这样,您就创建了一串最终指向您系统时区的链接。

/etc/localtime -> /usr/share/zoneinfo/America/Los_Angeles

现在取你创建的链接的名称(当地时间在我的例子中),并将其用作 postgresql.conf 中配置项的值

TimeZone = 'localtime'

重新启动 postgresql 并使用“SELECT now();”和“show timezone;”检查时间

相关内容