我有几个 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;”检查时间