【问题标题】:Postgres: "AT TIME ZONE 'localtime'"== "AT TIME ZONE 'utc'"?Postgres:“在时区'本地时间'”==“在时区'utc'”?
【发布时间】:2017-04-23 03:31:40
【问题描述】:

我很难理解"AT TIME ZONE 'localtime'" 究竟是如何工作的?通过玩它,我发现它的行为与"AT TIME ZONE 'UTC'" 完全一样……但是为什么呢? "localtime" 在 postgres 中是 "UTC" 的同义词吗?或者它来自某些设置(环境?连接时区?虽然都检查了,但似乎它们不相关)......

"localtime" function,但我认为这里不涉及。

示例 SQL:

# date
Thu Dec  8 12:00:05 AEDT 2016

# SELECT LOCALTIMESTAMP;
----------------------------
 2016-12-08 01:13:29.444725

# SELECT LOCALTIMESTAMP AT TIME ZONE 'America/New_York';
-------------------------------
 2016-12-08 06:08:31.183103+00

# SELECT LOCALTIMESTAMP AT TIME ZONE'localtime';
------------------------------
 2016-12-08 01:09:25.294063+00

# SELECT LOCALTIMESTAMP AT TIME ZONE 'utc';
 -------------------------------
 2016-12-08 01:09:44.32587+00 -- SAME AS ABOVE

 # SET TIME ZONE 'America/New_York';

 # SELECT LOCALTIMESTAMP;
 ----------------------------
  2016-12-07 20:13:34.924647

 # SELECT LOCALTIMESTAMP AT TIME ZONE 'localtime';
 ------------------------------
  2016-12-07 15:10:08.188197-05

 # SELECT LOCALTIMESTAMP AT TIME ZONE 'utc';
 ------------------------------
  2016-12-07 15:10:44.88332-05 -- SAME AS ABOVE

有什么提示吗?它是否记录在某处?

【问题讨论】:

  • 这样的问题必须提供正在使用的 Postgres 版本。也相关:服务器操作系统和时区设置,以及使用 `SET TIME ZONE. And do you have a non-default setting for timezone_abbreviations` 使用 SHOW timezone before 得到什么?

标签: postgresql time timezone


【解决方案1】:

Postgres 中的时间戳实际上并不存储任何时区信息。相反,此信息来自服务器设置的时区。在内部,所有时间戳信息都以 UTC 时间记录。因此,例如,如果您存储的时间戳信息来自 UTC 以外的时区,Postgres 会先将该时间戳转换为 UTC,然后再存储它。

来自documentation

对于带时区的时间戳,内部存储的值始终采用 UTC(通用协调时间,传统上称为格林威治标准时间,GMT)。使用该时区的适当偏移量将具有指定明确时区的输入值转换为 UTC。如果输入字符串中没有说明时区,则假定它在系统的 timezone 参数指示的时区中,并使用时区的偏移量转换为 UTC。

对于您的实际问题,localtime 只是服务器的时区,始终为 UTC。

此外,Postgres 的 localtime 似乎只是包装了 C 库函数 localtime(),它试图查找本地系统时间(默认为 UTC 时间)。同样,来自documentation

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

【讨论】:

  • localtime is just the timezone of the server which is always UTC 谢谢你的回复。但是,它是否记录在某处?我可以更改它吗?如何更改?只想了解所有的进出。
  • @stillwaiting Postgres 的locatime 似乎只是包装了C 库函数localtime(),它获取本地UTC 系统时间。所以这可能是不可能改变的。如果您在 Postgres 中指定时区,那么它将使用它来代替。
  • 请注意,虽然timestamp 类型不存储时区信息,但timestamptz 类型可以。使用timestamptztimestamp 更不容易出错,因为任何给定的时间戳都可以在时区之间正确转换。当时间戳是在与数据库不同时区运行的代码中生成时尤其如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 2019-05-31
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2019-03-09
相关资源
最近更新 更多