如何在 Postgres 9.3 中获取当前时区名称?
Posted
技术标签:
【中文标题】如何在 Postgres 9.3 中获取当前时区名称?【英文标题】:How do I get the current timezone name in Postgres 9.3? 【发布时间】:2015-03-28 19:25:15 【问题描述】:我想获取当前时区名称。
我已经实现的是通过以下方式获得utc_offset
/ 时区缩写:
SELECT * FROM pg_timezone_names WHERE abbrev = current_setting('TIMEZONE')
这给了我这个时区的所有大陆/首都组合,但不是确切的timezone
。例如我得到:
Europe/Amsterdam
Europe/Berlin
服务器在Berlin
,我想获取服务器的时区名称。
我对@987654327@ 的问题是它始终是UTC+01:00
,而不是DST iirc
。
【问题讨论】:
柏林和阿姆斯特丹的正确时区名称是欧洲中部时间 (CET)。一般来说,时区名称和缩写没有很好的定义;尽管有 ISO 标准,但许多国家/地区使用自己的定义。 PostgreSQL 支持也不完善,详情请见postgresql.org/docs/9.4/static/datetime-config-files.html。 在 pg_timezone_names 表中,CET 被定义为缩写,例如“Europe/Berlin”作为名称。我需要名称而不是缩写。 我在之前的评论中提供的链接向您展示了如何编辑文件以提供所需的内容。这是最好的。 所以 postgres 无法告诉我我是在“欧洲/柏林”还是“欧洲/阿姆斯特丹”,只是我在 CET 时区? 你能编辑你的问题并定义“我在”吗?服务器(通常)位于固定位置,时区取自操作系统或配置文件。 tz 名称与服务器一样固定。那么您确实想要服务器的时区名称还是数据库中数据的时区名称? 【参考方案1】:我认为在最一般的情况下单独使用 PostgreSQL 是不可能的。安装 PostgreSQL 时,您选择了一个时区。我很确定默认是使用操作系统的时区。这通常会在 postgresql.conf 中反映为参数“timezone”的值。但该值最终为“本地时间”。您可以使用 SQL 语句查看此设置。
show timezone;
但是,如果您将 postgresql.conf 中的时区更改为“Europe/Berlin”之类的内容,那么 show timezone;
将返回 那个 值而不是“localtime”。
所以我认为您的解决方案将涉及将 postgresql.conf 中的“时区”设置为显式值,而不是默认的“本地时间”。
【讨论】:
感谢您的回答。无法获得系统时区有点奇怪。 设置时区可以使用set timezone to 'UTC'
。
@ivkremer: set timezone
设置一个客户端会话的时区;它没有为 PostgreSQL 服务器设置时区。
@MikeSherrill'CatRecall' 谢谢,我没查。【参考方案2】:
它似乎在 Postgresql 9.5 中运行良好:
SELECT current_setting('TIMEZONE');
【讨论】:
我运行了你的命令,它返回了 15,200 行,尽管它们都是相同的时区。 @SubhenduMahanta 听起来您(或您的 IDE)包含了FROM
子句。在这种特殊情况下,您不需要一个。【参考方案3】:
这可能会也可能不会帮助您解决您的问题,OP,但是要获得当前服务器相对于 UTC 的时区(技术上是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)
(docs).
【讨论】:
另一个用户 suggested 使用SELECT EXTRACT(TIMEZONE_HOUR FROM now())
,但这有点危险,因为它忽略存在一半和四分之一时区的事实在那里。 @giladMayani
"朝鲜、纽芬兰、印度、伊朗、阿富汗、委内瑞拉、缅甸、斯里兰卡、马克萨斯以及澳大利亚的部分地区使用标准时间半小时偏差。一些国家,例如尼泊尔,以及一些省份,例如查塔姆群岛,使用刻钟偏差。” (link)【参考方案4】:
您可以通过以下脚本访问时区:
SELECT * FROM pg_timezone_names WHERE name = current_setting('TIMEZONE');
current_setting('TIMEZONE') 将为您提供设置的大陆/首都信息
pg_timezone_names 视图 pg_timezone_names 提供了一个时区名称列表,这些名称是
由 SET TIMEZONE 识别,以及它们相关的缩写、UTC 偏移量和
夏令时状态。
视图中的名称列 (pg_timezone_names) 是时区名称。
输出将是:
name- Europe/Berlin,
abbrev - CET,
utc_offset- 01:00:00,
is_dst- false
【讨论】:
【参考方案5】:看到这个答案:Source
如果在 postgresql.conf 中或服务器命令行选项中没有指定时区,服务器会尝试使用 TZ 环境变量的值作为默认时区。如果 TZ 未定义或不是 PostgreSQL 已知的任何时区名称,则服务器尝试通过检查 C 库函数 localtime() 的行为来确定操作系统的默认时区。默认时区被选为 PostgreSQL 已知时区中最接近的匹配。 (如果未指定,这些规则也用于选择 log_timezone 的默认值。)source
这意味着如果您不定义时区,服务器会尝试通过检查 C 库函数 localtime() 的行为来确定操作系统的默认时区。
如果 postgresql.conf 中未指定 timezone 或作为服务器命令行选项,服务器会尝试使用 TZ 环境变量的值作为默认时区。
看来确实可以设置系统时区。
从 shell 获取操作系统本地时区。在 psql 中:
=> \! date +%Z
【讨论】:
date +%Z
命令将返回客户端的时区,而不是您通过 psql
连接的服务器以上是关于如何在 Postgres 9.3 中获取当前时区名称?的主要内容,如果未能解决你的问题,请参考以下文章
使用 node-postgres 在 utc 中获取 Postgres“没有时区的时间戳”