受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

B.5. POSIX 时区规范 #

PostgreSQL 可以接受按照 POSIX 标准为 TZ 环境变量规定的规则编写的时区规范。POSIX 时区规范不足以处理真实世界时区历史的复杂性,但有时仍有使用它们的理由。

POSIX 时区规范的形式为

STD offset [ DST [ dstoffset ] [ , rule ] ]

(为便于阅读,这里把字段之间的空格写了出来,但实际使用时不应包含空格。)各字段含义如下:

  • STD 是标准时间所使用的时区缩写。

  • offset 是该时区标准时间相对 UTC 的偏移。

  • DST 是夏令时所使用的时区缩写。如果省略这个字段以及其后的字段,则该时区使用固定的 UTC 偏移,没有夏令时规则。

  • dstoffset 是夏令时相对 UTC 的偏移。这个字段通常会被省略,因为它默认比标准时间的 offset 少一小时,而这通常正是正确的设置。

  • rule 定义夏令时何时生效的规则,如下所述。

在这种语法中,时区缩写可以是由字母组成的字符串,如 EST;也可以是用尖括号括起来的任意字符串,如 <UTC-05>。注意,这里给出的时区缩写只用于输出,而且即便如此,也只在某些时间戳输出格式中使用。时间戳输入中可识别的时区缩写按 Section B.4 中说明的方式确定。

偏移字段指定与 UTC 的时差,可以写成小时,并可选地带分钟和秒。其格式为 hh[:mm[:ss]],并可选带前导符号(+-)。正号用于格林尼治以西的时区。(注意,这与 PostgreSQL 其他地方使用的 ISO-8601 符号约定正好相反。)hh 可以是一位或两位数字;mmss(如果使用)必须是两位数字。

夏令时转换 rule 的格式为

dstdate [ / dsttime ] , stddate [ / stdtime ]

(同前,实际使用时不应包含空格。)dstdatedsttime 字段定义夏令时何时开始,而 stddatestdtime 定义标准时间何时开始。(在某些情况下,尤其是在赤道以南的时区中,前者在一年中可能晚于后者。)日期字段具有下列格式之一:

n

一个普通整数表示一年中的第几天,从 0 开始计,到 364 为止;闰年则到 365 为止。

Jn

在这种形式中,n 从 1 计到 365,即使存在 2 月 29 日也不计入。(因此,发生在 2 月 29 日的转换无法用这种方式指定。不过,2 月之后的日期无论是否闰年,编号都相同,所以对于固定日期上的转换,这种形式通常比普通整数形式更有用。)

Mm.n.d

这种形式指定一个总是发生在同一个月份、同一个星期几的转换。m 表示月份,范围是 1 到 12。n 指定由 d 标识的星期几在该月中第 n 次出现。n 是 1 到 4 之间的数字,或者是 5,表示该月中该星期几最后一次出现(可能是第四次,也可能是第五次)。d 是 0 到 6 之间的数字,其中 0 表示星期日。例如,M3.2.0 表示3 月的第二个星期日

Note

M 格式足以描述许多常见的夏令时转换规则。但请注意,这些变体都无法处理夏令时法规的变更,因此在实践中,要正确解释过去的时间戳,就需要依赖命名时区中保存的历史数据(位于 IANA 时区数据库中)。

转换规则中的时间字段格式与前面描述的偏移字段相同,只是它们不能包含符号。它们定义了本地当前时间切换到另一种时间的时刻。如果省略,则默认值为 02:00:00

如果给出了夏令时时区缩写,但省略了转换 rule 字段,则回退行为会使用规则 M3.2.0,M11.1.0,它对应于美国截至 2020 年的做法(也就是说,3 月的第二个星期日春季拨快,11 月的第一个星期日秋季回拨,两次转换都发生在当时有效时间的 2AM)。请注意,这个规则不能给出 2007 年之前美国正确的转换日期。

例如,CET-1CEST,M3.5.0,M10.5.0/3 描述了巴黎当前(截至 2020 年)的计时做法。这个规范表明标准时间的缩写是 CET,并且比 UTC 快 1 小时(即位于其东侧);夏令时的缩写是 CEST,并且隐含地比 UTC 快 2 小时;夏令时从 3 月最后一个星期日的 2AM CET 开始,到 10 月最后一个星期日的 3AM CEST 结束。

这四个时区名称 EST5EDTCST6CDTMST7MDTPST8PDT 看起来像是 POSIX 时区规范。不过,它们实际上会被当作命名时区处理,因为(出于历史原因)IANA 时区数据库中存在这些名称对应的文件。这在实践中的含义是:这些时区名称会给出有效的美国历史夏令时转换,即使普通的 POSIX 规范做不到这一点。

需要注意的是,POSIX 风格时区规范很容易拼错,因为系统不会检查时区缩写是否合理。例如,SET TIMEZONE TO FOOBAR0 也能工作,从而使系统实际上使用了一个相当古怪的 UTC 缩写。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。