# B.5.POSIX时区规范
PostgreSQL可以接受根据POSIX标准的时区规则编写的时区规范TZ
环境变量。POSIX时区规范不足以处理现实世界时区历史的复杂性,但有时有理由使用它们。
POSIX时区规范的格式如下
STD offset [ DST [ dstoffset ] [ , rule ] ]
(为了可读性,我们在字段之间显示空格,但实际上不应使用空格。)这些字段是:
*
性病科
*是用于标准时间的区域缩写。*
抵消
*是区域与UTC的标准时间偏移。*
DST
*是用于夏令时的区域缩写。如果省略此字段和以下字段,则分区将使用固定的UTC偏移量,而不使用夏令时规则。DST偏移量
是与UTC的夏令时偏移量。此字段通常被忽略,因为它默认为比标准时间少一小时抵消
,这通常是正确的。*
规则
*定义夏令时生效的规则,如下所述。在这种语法中,区域缩写可以是一串字母,例如
美国东部时间
,或由尖括号包围的任意字符串,例如<UTC-05>
.请注意,此处给出的区域缩写仅用于输出,甚至仅在某些时间戳输出格式中使用。时间戳输入中识别的区域缩写如中所述确定B.4节.偏移字段指定与UTC的小时差,以及可选的分钟和秒差。他们有格式*
啊
[:
嗯
[:
党卫军
]]可以选择带前导符号(+
或-
).正号表示区域西格林威治的。(请注意,这与PostgreSQL中其他地方使用的ISO-8601符号约定相反。)啊
可以有一个或两个数字;嗯
和党卫军
*(如果使用)必须有两个。夏时制的转变*
规则
*有格式吗
dstdate [ / dsttime ] , stddate [ / stdtime ]
(与之前一样,实践中不应包含空格。)这个*日期
和时间
字段定义夏令时开始的时间,而stddate
和标准时间
*定义标准时间的开始时间。(在某些情况下,尤其是在赤道以南的地区,前者可能比后者晚。)日期字段有以下格式之一:
n
纯整数表示一年中的一天,从零到364,或闰年到365.
J
n
以这种形式,*n
*计数范围从1到365,2月29日即使存在也不计算。(因此,2月29日发生的过渡不能用这种方式指定。但是,2月后的几天无论是否闰年都有相同的数字,因此对于固定日期的过渡,这种形式通常比普通整数形式更有用。)
M
m
.
n
.
d
此表单指定了总是在同一个月和一周的同一天发生的转换。m
标识月份,从1到12.n
指定n
“工作日的第次事件,由*d
*. *n
是一个介于1和4之间的数字,或5表示该月的最后一个工作日(可能是第四个或第五个)。d
*是介于0和6之间的数字,0表示星期天。例如M3.2
意思是“三月的第二个星期日”。
# 笔记
这个米
格式足以描述许多常见的夏令时过渡规律。但请注意,这些变体都不能处理夏令时法律的变化,因此在实践中,为命名时区(在 IANA 时区数据库中)存储的历史数据对于正确解释过去的时间戳是必要的。
转换规则中的时间字段与前面描述的偏移字段具有相同的格式,只是它们不能包含符号。它们定义发生更改为其他时间的当前本地时间。如果省略,则默认为02:00:00
.
如果给出了夏令时缩写,但转换*规则
*字段被省略,回退行为是使用规则M3.2.0,M11.1.0
,这对应于截至 2020 年的美国做法(即,在 3 月的第二个星期日向前推进,在 11 月的第一个星期日回退,这两个转换都发生在主要时间凌晨 2 点)。请注意,该规则并未给出 2007 年之前的正确美国过渡日期。
举个例子,CET-1CEST,M3.5.0,M10.5.0/3
描述了巴黎当前(截至 2020 年)的计时实践。该规范说标准时间有缩写中考
并且比 UTC 早(东)一小时;夏令时有缩写CEST
并且隐含地比 UTC 早两个小时;夏令时从欧洲中部时间三月最后一个星期日凌晨 2 点开始,到十月最后一个星期日凌晨 3 点结束。
四个时区名称EST5EDT
,CST6CDT
,MST7MDT
, 和PST8PDT
看起来它们是 POSIX 区域规范。但是,它们实际上被视为命名时区,因为(出于历史原因)在 IANA 时区数据库中有这些名称的文件。这样做的实际含义是,这些区域名称将产生有效的历史美国夏令时转换,即使普通的 POSIX 规范不会。
应该注意,POSIX 风格的时区规范很容易拼错,因为没有检查时区缩写的合理性。例如,将时区设置为 FOOBAR0
将起作用,使系统有效地使用 UTC 的一个相当特殊的缩写。