【问题标题】:How to get server OS local time in all Postgres versions如何在所有 Postgres 版本中获取服务器操作系统本地时间
【发布时间】:2016-11-24 22:17:42
【问题描述】:

如何在每个 Postgres 版本中以 char(8) 格式 hh:mm:ss 获取服务器本地时间。

在 9.1 中它可以工作:

select current_time::char(8)

返回正确的当地时间 13:46:00

在 9.5 中,它返回 3 小时不同的时间:

10:46:00

选择 current_time,version() 返回

"10:48:40.181735+00";"PostgreSQL 9.5.2, compiled by Visual C++ build 1800, 32-bit"

"13:48:51.775138+03";"PostgreSQL 9.1.2 on x86_64-unknown-linux-gnu, compiled by gcc-4.4.real (Debian 4.4.5-8) 4.4.5, 64-bit"

更新

两台服务器都使用默认的 postgres.conf 时间设置。 postgres.conf 不包含时区设置。

在 9.5 Windows 10 中包含

#timezone = 'GMT'
#timezone_abbreviations = 'Default'     

在 9.1 Debian 中包含

#timezone = '(defaults to server environment setting)'
#timezone_abbreviations = 'Default'

9.5 使用默认 postgresql.conf 文件时如何获取服务器本地时间?

看起来服务器不使用 9.5 中的操作系统设置

如何强制 9.5 向操作系统询问时区并返回该时区的时间?

【问题讨论】:

  • 您能否检查这两个版本之间的时区是否存在差异?我相信这会在 postgresql.conf 文件中eureka.ykyuen.info/2014/08/15/postgresql-set-and-get-timezone
  • 我用时区信息更新了问题。 9.5 使用默认 postgresql.conf 文件时如何获取服务器本地时间?
  • “当使用默认 postgresql.conf 文件时”是什么意思?你不能在 postgresql.conf 中更改时区设置吗?
  • 我正在寻找一种方法来创建适用于任何 postgresql.conf 设置的应用程序。 set timezone='gmt-3'; select current_time::char(8) 有效,但它使用硬编码的时区。如何用服务器操作系统时区替换gmt-3
  • 这个要求有点奇怪。通常使用客户端时区。为什么是服务器一?你能详细说明一下吗?

标签: sql postgresql


【解决方案1】:

询问您想要的time zone

select current_time at time zone 'brt';
      timezone      
--------------------
 08:26:16.778448-03

如果你需要一个字符串:

select to_char(current_timestamp at time zone 'brt', 'HH24:MI:SS');
 to_char  
----------
 08:32:07

注意to_char 函数不接受time 类型。请改用timestamp

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

$ date +%Z
BRT

在 psql 中:

=> \! date +%Z
BRT

如果客户端有psql:

psql -c "\! date +%Z" --host localhost --dbname=cpn --no-password
BRT

需要一个.pgpass 文件以避免提供密码。

【讨论】:

  • 这使用硬编码的时区 brt 。应用程序使用来自不同时区的服务器。如何使用服务器操作系统时区?
  • 应用程序正在以非超级用户权限运行。它如何强制服务器获取操作系统时区?
  • @Andrus 无需成为超级用户即可获取操作系统时区。我以非超级用户身份发出了上述 shell 调用。
  • 应用程序只能使用 5432 端口访问服务器。没有 SSH 访问服务器,所有其他端口都关闭。在这种情况下如何获取服务器操作系统时间?
【解决方案2】:

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

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

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

我相信您需要删除#timezone = 'GMT' 中的# 并将GMT 替换为'(defaults to server environment setting)' 因为'(defaults to server environment setting)' 未定义,因此服务器尝试通过检查C 库函数localtime() 的行为来确定操作系统的默认时区。

【讨论】:

  • 在 9.5 The built-in default is GMT 中,它不会尝试确定它 (postgresql.org/docs/9.5/static/… ) 如何在不更改 postgresql.conf 文件的情况下始终使用服务器操作系统时间?
  • 每次安装新的 postgresql 服务器时,都会要求您设置一个时区,如果您不选择一个,则(如您所述)默认设置为(9.5:GMT)。该文档还指出:,但这通常在 postgresql.conf 中被覆盖。因此,如果您在安装时未选择时区或稍后在 postgresql.conf 中更改时区,则无法“自动选择”机器默认值
  • 服务器安装时不询问时区。应用程序无法控制 postgres 服务器的安装方式,也无权更改 postgresql.conf。它以非超级用户权限运行。在这种情况下如何获取操作系统时区?
  • 检查 postgresql.conf 文件的权限和所有者。还要确保编辑正确的配置文件,运行sudo -u postgres /usr/local/pgsql/bin/psql 并输入SHOW config_file; 还要检查您用来更改postgresql 设置的用户是否有足够的权限。
  • 应用程序只能使用 5432 端口访问服务器。没有 SSH 访问服务器,所有其他端口都关闭。在这种情况下如何获取服务器操作系统时间?
【解决方案3】:

获取使用定义的时区计算的本地时间:

select current_time, version();

获取指定时区计算的本地时间:

select current_time at time zone 'US/Eastern';

获取定义的时区:

SELECT current_setting('TIMEZONE');

分配您要使用的时区:

set timezone='US/Eastern';

你可以看到不同的时区here

猜你喜欢
  • 2010-10-08
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
  • 2019-03-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
相关资源
最近更新 更多