PostgreSQL应该用哪个时区表示符?

PG中国用哪个时区标识符?

在linux中使用timedatectl查看时间,可以看到localtime中时区是CST

$ timedatectl 
  Local time: Mon 2024-03-04 18:19:54 CST
  Universal time: Mon 2024-03-04 10:19:54 UTC
  RTC time: Mon 2024-03-04 10:19:53
  Time zone: Asia/Shanghai (CST, +0800)

CST是一个多重含义的时区缩写,可表示以下时区:

  • 美国中部时间:Central Standard Time (USA) UT-6:00
  • 澳大利亚中部时间:Central Standard Time (Australia) UT+9:30
  • 中国标准时间:China Standard Time UT+8:00
  • 古巴标准时间:Cuba Standard Time UT-4:00

但在PG中,CST 这个时区会被处理为 -6 时区(美国中部时间)。所以如果PG中如果用的时区标识符为CST,可能会带来些问题。 PG中可以使用 'Asia/Hong_Kong' 作为时区替代,其他如'Hongkong', 'Etc/GMT-8'也可以。

postgres=# \d+ tt_cst 
                                            Table "public.tt_cst"
 Column |            Type             | Collation | Nullable | Default | Storage | Stats target | Description 
--------+-----------------------------+-----------+----------+---------+---------+--------------+-------------
 f1     | integer                     |           |          |         | plain   |              | 
 f2     | timestamp without time zone |           |          |         | plain   |              | 
 f3     | timestamp with time zone    |           |          |         | plain   |              | 
 f4     | timestamp with time zone    |           |          |         | plain   |              | 
Access method: heap

postgres=# show timezone;
   TimeZone    
---------------
 Asia/Shanghai
(1 row)

postgres=# insert into tt_cst values(1,'2024-03-08 17:56:48 CST','2024-03-08 17:56:48 CST','2024-03-08 17:56:48 HKT');
INSERT 0 1
postgres=# select * from tt_cst ;
 f1 |         f2          |           f3           |           f4           
----+---------------------+------------------------+------------------------
  1 | 2024-03-08 17:56:48 | 2024-03-09 07:56:48+08 | 2024-03-08 17:56:48+08
(1 row)
-- 插入的3个时间数据,f2列因为ts without time zone的,所以直接忽略了时区标识符CST,f3列PG把CST时区解析为美国中部时间:Central Standard Time (USA) UT-6:00,pg系统的时区是Asia/Shanghai即UT+8:00,相差了14小时,所以f2列数据插入时要时区换算,'2024-03-08 17:56:48 CST'的基础上+14小时,即'2024-03-09 07:56:48+08';另外f4列采用了HKT即Asia/Hong_Kong来标示中国时区+08,则没有问题。

当然,pg中+08时区的时区标识符还有其他(如下),也可以用来做为中国localtime的时区。

postgres=# select * from pg_timezone_names where utc_offset='08:00:00';
        name        | abbrev | utc_offset | is_dst 
--------------------+--------+------------+--------
 Asia/Makassar      | WITA   | 08:00:00   | f
 Asia/Kuching       | +08    | 08:00:00   | f
 Asia/Ulaanbaatar   | +08    | 08:00:00   | f
 Asia/Choibalsan    | +08    | 08:00:00   | f
 Asia/Manila        | PST    | 08:00:00   | f
 Asia/Singapore     | +08    | 08:00:00   | f
 Asia/Irkutsk       | +08    | 08:00:00   | f
 Asia/Brunei        | +08    | 08:00:00   | f
 Asia/Kuala_Lumpur  | +08    | 08:00:00   | f
 Asia/Chongqing     | CST    | 08:00:00   | f
 Asia/Harbin        | CST    | 08:00:00   | f
 Asia/Chungking     | CST    | 08:00:00   | f
 Asia/Macao         | CST    | 08:00:00   | f
 Asia/Ujung_Pandang | WITA   | 08:00:00   | f
 Asia/Ulan_Bator    | +08    | 08:00:00   | f
 Asia/Shanghai      | CST    | 08:00:00   | f
 Asia/Hong_Kong     | HKT    | 08:00:00   | f
 Asia/Taipei        | CST    | 08:00:00   | f
 Asia/Macau         | CST    | 08:00:00   | f
 Australia/Perth    | AWST   | 08:00:00   | f
 Australia/West     | AWST   | 08:00:00   | f
 Etc/GMT-8          | +08    | 08:00:00   | f
 Hongkong           | HKT    | 08:00:00   | f
 PRC                | CST    | 08:00:00   | f
 ROC                | CST    | 08:00:00   | f
 Singapore          | +08    | 08:00:00   | f
(26 rows)

参考

PostgreSQL: Documentation: 7.2: Time Zones

posted @ 2024-03-08 18:14  清风生  阅读(358)  评论(0)    收藏  举报