在Postgres 9.3中如何获取当前时区名称?

144

我想获取当前时区的名称。 我已经通过以下方式获得了utc_offset / 时区缩写:

SELECT * FROM pg_timezone_names WHERE abbrev = current_setting('TIMEZONE')

这为我提供了该时区下所有的大洲/首都组合,但没有精确的时区信息。例如,我会得到:

Europe/Amsterdam
Europe/Berlin

服务器在 Berlin,我想获取服务器的时区名称。

我对CET的问题是它总是 UTC+01:00,而不考虑DST iirc


1
在pg_timezone_names表中,CET被定义为缩写,例如“Europe/Berlin”是名称。我需要的是名称而不是缩写。 - Deutro
我在之前的评论中提供的链接向您展示了如何编辑文件以提供所需内容。这就是最好的方法了。 - Patrick
PostgreSQL 没有办法告诉我,我是在“Europe/Berlin” 还是 “Europe/Amsterdam”,只知道我在 CET 时区吗? - Deutro
你能否编辑你的问题并定义“我在哪里”?服务器(通常)位于固定位置,时区取决于操作系统或配置文件。tz名称与服务器一样固定。所以,您确实想要服务器的时区名称还是数据库中的数据? - Patrick
编辑了我的问题。希望这能帮助你理解我真正想要实现的目标。 - Deutro
显示剩余2条评论
5个回答

198

我认为在最一般的情况下,仅使用PostgreSQL是不可能实现的。当您安装PostgreSQL时,需要选择一个时区。我相信默认设置是使用操作系统的时区。通常会在postgresql.conf中以参数“timezone”的值反映出来。但是该值最终变成“localtime”。您可以使用SQL语句查看此设置。

show timezone;

但是,如果您在postgresql.conf中更改时区为类似于"Europe/Berlin"的内容,则show timezone;将返回值而不是"localtime"。

因此,我认为您的解决方案将涉及在postgresql.conf中将"timezone"设置为明确的值,而不是默认值"localtime"。


1
谢谢您的回答。有点奇怪不能获取系统时区。 - Deutro
6
要设置时区,可以使用set timezone to 'UTC' - ivkremer
2
@ivkremer: set timezone 设置一个客户端会话的时区;它不会设置 PostgreSQL 服务器的时区。 - Mike Sherrill 'Cat Recall'
@MikeSherrill'CatRecall' 谢谢,我没有检查它。 - ivkremer

50

PostgreSQL 9.5中似乎能够正常工作:

SELECT current_setting('TIMEZONE');

我运行了你的命令,它返回了15,200行数据,尽管它们都是同一个时区。 - Subhendu Mahanta
@SubhenduMahanta 听起来像是你(或者你的IDE)包含了一个FROM子句。在这种特定情况下,你不需要它。 - koyae

32

这可能有助于解决您的问题,楼主,但要获取当前服务器相对于世界协调时间(UT1, 技术上),可以执行以下操作:

SELECT EXTRACT(TIMEZONE FROM now())/3600.0;

以上工作是通过提取UT1相关偏移量(单位为分钟),然后使用3600秒/小时的转换因子将其转换为小时。

示例:

SET SESSION timezone TO 'Asia/Kabul';
SELECT EXTRACT(TIMEZONE FROM now())/3600.0;
-- output: 4.5 (as of the writing of this post)

(文档).


6
另一位用户建议使用SELECT EXTRACT(TIMEZONE_HOUR FROM now()),但这可能有点危险,因为它会忽略存在“半个”和“四分之一”的时区这一事实。@giladMayani - koyae
3
北朝鲜、纽芬兰、印度、伊朗、阿富汗、委内瑞拉、缅甸、斯里兰卡、马尔凯萨斯群岛以及澳大利亚某些地区采用比标准时间提前或推迟半个小时的时区偏移量。一些国家(如尼泊尔)和一些省份(如查塔姆群岛)则使用比半小时更小的偏移量。 - koyae

26

您可以通过以下脚本访问时区:

SELECT * FROM pg_timezone_names WHERE name = current_setting('TIMEZONE');
  • current_setting('TIMEZONE')将为您提供设置的大陆/首都信息
  • pg_timezone_names视图提供了一份由SET TIMEZONE识别的时区名称列表,以及它们关联的缩写、UTC偏移和夏令时状态。
  • 视图(pg_timezone_names)中的名称列是时区名称。

输出结果将是:

name- Europe/Berlin, 
abbrev - CET, 
utc_offset- 01:00:00, 
is_dst- false

11

请参考此答案:来源

如果在postgresql.conf文件或服务器命令行选项中未指定时区,则服务器将尝试使用TZ环境变量的值作为默认时区。如果未定义TZ或未使用PostgreSQL已知的任何时区名称,则服务器将通过检查C库函数localtime()的行为来确定操作系统的默认时区。默认时区是在PostgreSQL已知的时区中选择最接近匹配的时区。(如果未指定,这些规则也用于选择log_timezone的默认值。)来源

这意味着如果您没有定义时区,服务器将通过检查C库函数localtime()的行为来确定操作系统的默认时区。

如果在postgresql.conf文件或服务器命令行选项中未指定时区,则服务器将尝试使用TZ环境变量的值作为默认时区。

看起来确实可以设置系统的时区。

从shell获取操作系统本地时区。在psql中:

=> \! date +%Z

3
date +%Z 命令会返回客户端的时区,而不是你通过 psql 连接的服务器的时区。 - Eugen Konkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接