通常,如果日期/时间字符串语法有效但包含超出范围的字段值,系统会抛出错误。例如,指定 2 月 31 日的输入将被拒绝。
在夏令时转换期间,可能会出现一个看似有效的 Timestamp 字符串表示一个不存在或不明确的时间戳。此类案例不会被拒绝;通过确定要应用的 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 直接跳变到东部夏令时间 3AM。 PostgreSQL 将给出的时间解释为标准时间 (UTC-5),然后显示为东部夏令时间 (UTC-4) 的 3:30AM。
相反,请考虑回退转换期间的行为
=> SELECT '2018-11-04 01:30'::timestamptz; timestamptz ------------------------ 2018-11-04 01:30:00-05 (1 row)
在该日期,可能 1:30AM 有两种解释;一是东部夏令时间 1:30AM,然后时钟从东部夏令时间 2AM 跳回到东部标准时间 1AM 后一个小时,即东部标准时间 1:30AM。同样,PostgreSQL 将给出的时间解释为标准时间 (UTC-5)。我们可以通过指定夏令时来强制执行其他解释
=> SELECT '2018-11-04 01:30 EDT'::timestamptz; timestamptz ------------------------ 2018-11-04 01:30:00-04 (1 row)
在此类案例中应用的精确规则是,一个似乎落在夏令时提前转换范围内的无效 Timestamp 会分配转换之前时区中流行的 UTC 偏移量,而一个可能落在夏令时回退转换任一侧的含糊 Timestamp 会分配转换后时区中流行的 UTC 偏移量。在大多数时区,这等同于在存在疑问时优先使用标准时间解释。
在所有案例中,Timestamp 关联的 UTC 偏移量都可以明确指定,方法是使用数字 UTC 偏移量或与固定 UTC 偏移量相对应的时区缩写。仅在有必要为偏移量在不断变化的时区推断出 UTC 偏移量时,才会适用刚才给出的规则。