由 John Doe 六月 3, 2025
你的应用软件需要支持多时区吗?或者,你需要在多个时区之间转换时间吗?
特性提交日志
添加对 AT LOCAL 的支持。
当在带时区或不带时区的时间戳之间进行转换时,SQL 标准规定了 AT TIME ZONE 的 AT LOCAL 变体,该变体使用会话的时区。这包括三个系统函数,它们能够以一种与现有的 AT TIME ZONE 形式相同的方式执行转换工作,但需要将这些函数标记为 stable(稳定),因为它们依赖于会话的 timezone 参数设置。
讨论:https://postgr.es/m/8e25dec4-5667-c1a5-6581-167d710c2182@postgresfriends.org
示例
本次提交的特性,让 PostgreSQL 可以支持使用 “AT LOCAL” 语法转换为本地会话的时区。
让我们看看如何进行时区转换。以下是一个非常简单的示例:
postgres=# show timezone;
TimeZone
---------------
Asia/Shanghai
(1 row)
postgres=# select now();
now
-------------------------------
2025-05-02 21:43:28.395172+08
(1 row)
postgres=# select now() at time zone 'UTC';
timezone
---------------------------
2025-05-02 13:43:36.80314
(1 row)
postgres=# select now() at time zone 'UTC-8';
timezone
----------------------------
2025-05-02 21:44:11.295156
(1 row)
这将返回当前时间,以 “UTC” 和 “UTC-8”(服务器当前的时区)表示。更易读的格式是使用时区名称,例如:
postgres=# select now() at time zone 'Asia/Shanghai';
timezone
----------------------------
2025-05-02 21:44:40.680735
(1 row)
所有可用的时区名称都列在系统视图 pg_timezone_names 中:
postgres=# select * from pg_timezone_names limit 10;
name | abbrev | utc_offset | is_dst
---------------------+--------+------------+--------
Arctic/Longyearbyen | CEST | 02:00:00 | t
Eire | IST | 01:00:00 | f
Egypt | EEST | 03:00:00 | t
CST6CDT | CDT | -05:00:00 | t
MST7MDT | MDT | -06:00:00 | t
Africa/Johannesburg | SAST | 02:00:00 | f
Africa/El_Aaiun | +01 | 01:00:00 | f
Africa/Banjul | GMT | 00:00:00 | f
Africa/Blantyre | CAT | 02:00:00 | f
Africa/Maputo | CAT | 02:00:00 | f
(10 rows)
如果您想知道 “Africa/Maputo” 的当前时间,这很简单:
postgres=# select now() at time zone 'Africa/Maputo';
timezone
----------------------------
2025-05-02 15:45:43.737949
(1 row)
使用新版本的 PostgreSQL,您还可以使用 “AT LOCAL” 语法:
postgres=# set timezone to 'Egypt';
SET
postgres=# select now() at local;
timezone
----------------------------
2025-05-02 16:46:29.448678
(1 row)
postgres=# select now() at local timezone;
timezone
---------------------------
2025-05-02 16:46:38.07518
(1 row)
postgres=# set timezone to 'Africa/Blantyre';
SET
postgres=# select now() at local;
timezone
----------------------------
2025-05-02 15:47:07.106363
(1 row)
postgres=# select now() at local timezone;
timezone
----------------------------
2025-05-02 15:47:13.321566
(1 row)
语法中的关键字 “timezone” 是可选的,可以省略。
非常不错的体验,感谢所有参与的社区人员。
参考
提交日志:https://git.postgresql.org/pg/commitdiff/97957fdbaa429c7c582d4753b108cb1e23e1b28a