Postgres 可以用 DST 区分时间戳吗?



在美国的11/4/12,冬季时钟从凌晨2点转移到凌晨1点。例如,2AM CDT变成了1AM CST。

这意味着凌晨 1:32 ">

发生了两次":1:32 CDT(纪元 1352010776642),一小时后 1:32 CST(纪元1352014376642)。

是否可以在PostgreSQL中以某种方式以纯timestamp类型区分两者?我们观察到的是,在 1:32 CDT 时,我们的应用程序将日期存储为 1352014376642("第二次出现")。

据我所知,没有。

TIMESTAMP WITHOUT TIME ZONE("普通timestamp"),就像您使用的那样,直接存储本地时间,同样不存储关联的 UTC 偏移量或时区。这是本地时间,因此除非您存储与该本地时间关联的时区,否则它可能是许多不同的时刻之一。

一旦转换为timestamptz并存储,就无法将'2012-01-01 11:00 +0800''2012-01-01 11:00 +0700'区分开来。因此,如果您的 DST 班次导致在不同的时区重播一小时,则无法重建该信息。证人:

regress=> select extract(epoch from '2012-01-01 11:00 +0800'::timestamp),
extract(epoch from '2012-01-01 11:00 +700'::timestamp);
date_part  | date_part  
------------+------------
1325415600 | 1325415600
(1 row)

如您所见,时区被忽略;它被剥离和丢弃。timestamp字段不是用于标识离散时间点的正确类型,因此您是 SOL。


顺便说一句,TIMESTAMP WITH TIME ZONE使用timezone设置将时间戳转换为 UTC 以进行存储,并转换回本地时区以进行检索。它描述了一个瞬间(大致见最后的链接)。这意味着在timestamptz,就像timestamp一样,原始时区丢失了。这令人困惑,并且似乎与数据类型的名称相矛盾。显然,这就是标准的方式,所以无论它是否愚蠢,我们都会坚持下去。要区分时间戳,您还需要存储关联的 UTC 偏移量。最好命名为TIMESTAMP WITH TIME ZONE CONVERSION.

这使得timestamptz适合存储离散时间点,但对于存储事件在现实世界本地时间发生的时间就没有多大好处了。同时存储 UTC 偏移量和/或 tzname。

看:

regress=> select extract(epoch from '2012-01-01 01:00 CST'::timestamptz),
extract(epoch from '2012-01-01 02:00 CDT'::timestamptz);
date_part  | date_part  
------------+------------
1325401200 | 1325401200

遗憾的是,没有数据类型将TIMESTAMP WITH TIME ZONE与内部 UTC 偏移量相结合,记录转换前的 TZ 偏移量。

也就是说,你不能依靠时钟来不加倍时间戳或以其他方式变得奇怪,所以有必要拥有非常健壮的代码,并且不相信它有多大意义。

相关内容

  • 没有找到相关文章

最新更新