Postgres可以将时间戳与DST区分开来吗?

时间:2012-11-05 11:51:40

标签: postgresql timezone dst

12月11日至4月4日,美国时钟从凌晨2点变为凌晨1点。例如,2AM CDT成为1AM CST。

这意味着上午1:32“发生了两次”:1:32 CDT(纪元1352010776642),1小时后1点32分CST(纪元1352014376642)。

是否有可能以某种方式区分PostgreSQL中的普通timestamp类型的两个?我们观察到的是,在CD的1:32,我们的应用程序存储日期为1352014376642(“第二次出现”)。

1 个答案:

答案 0 :(得分:2)

据我所知,没有。

TIMESTAMP WITHOUT TIME ZONE(“普通timestamp)就像你直接使用存储当地时间一样,同时没有存储相关的UTC偏移或时区。这是本地时间,所以除非您存储了时区与当地时间相关联,它可能是许多不同时刻之一。

转换为'2012-01-01 11:00 +0800'并存储后,无法将'2012-01-01 11:00 +0700'timestamptz区分开来。因此,如果您有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。


BTW,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与记录转换前TZ偏移量的内部UTC偏移量相结合。

那说,you can't rely on the clock not to double up timestamps or otherwise be bizarre无论如何,所以有必要让代码在时间上非常强大,并且不相信它有多大意义。