选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4
历史版本PostgreSQL 9.6 已于 2021 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

B.2. 处理无效或有歧义的时间戳 #

通常,如果一个日期/时间字符串在语法上有效,但包含超出范围的字段值,就会抛出错误。例如,指定 2 月 31 日的输入会被拒绝。

在夏令时转换期间,看似有效的时间戳字符串有可能表示一个不存在的时间戳,或者表示一个有歧义的时间戳。这类情况不会被拒绝;系统通过确定应采用哪个 UTC 偏移来消除歧义。例如,假设 TimeZone 参数被设置为 America/New_York,请看:

=> SELECT '2018-03-11 02:30'::timestamptz;
      timestamptz
------------------------
 2018-03-11 03:30:00-04
(1 row)

因为那一天在该时区是春季拨快的转换日,所以并不存在民用时间 2:30AM;时钟从 2AM EST 直接跳到 3AM EDT。PostgreSQL 将给定时间按标准时间(UTC-5)来解释,因此显示为 3:30AM EDT(UTC-4)。

相反,考虑秋季回拨转换期间的行为:

=> SELECT '2018-11-04 02:30'::timestamptz;
      timestamptz
------------------------
 2018-11-04 02:30:00-05
(1 row)

在那一天,2:30AM 有两种可能的解释;先有一次 2:30AM EDT,随后一小时后回拨到标准时间,于是又出现一次 2:30AM EST。再次,PostgreSQL 将给定时间按标准时间(UTC-5)来解释。我们可以通过显式指定夏令时来强制:

=> SELECT '2018-11-04 02:30 EDT'::timestamptz;
      timestamptz
------------------------
 2018-11-04 01:30:00-05
(1 row)

这个时间戳既可以合法地显示为 2:30 UTC-4,也可以显示为 1:30 UTC-5;时间戳输出代码选择了后者。

在这类情况下适用的精确规则是:如果一个无效时间戳看起来落在夏令时前向跳转转换之内,则为它分配该时区在转换前刚刚生效的 UTC 偏移;如果一个有歧义的时间戳可能落在回拨转换前后任一侧,则为它分配该时区在转换后刚刚生效的 UTC 偏移。在大多数时区,这等价于说拿不准时优先采用标准时间的解释

在任何情况下,都可以显式指定与时间戳相关联的 UTC 偏移,方法是使用数字形式的 UTC 偏移,或者使用对应于固定 UTC 偏移的时区缩写。上述规则只在需要为 UTC 偏移会变化的时区推断 UTC 偏移时才适用。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。