一般使用TIMESTAMPTZ
以下是 Postgres 专家 David E. Wheeler 在一篇博文中的建议,其标题说明了一切:
Always Use TIMESTAMP WITH TIME ZONE (TIMESTAMPTZ)
如果您要跟踪实际时刻、时间线上的特定点,请使用TIMESTAMP WITH TIME ZONE。
一个例外:分区
Wheeler 的唯一例外是在时间戳分区时,因为技术限制。对于我们大多数人来说,这是一个罕见的例外。
有关分区的信息,请参阅doc 和Wiki。
用词不当
数据类型名称timestamp with time zone 和timestamp without time zone 用词不当。在这两种情况中,日期时间值以 UTC 格式存储(无时区偏移)。再读一遍前面那句话。 UTC,始终。 “with time zone” 短语的意思是“注意时区”,而不是“将时区存储在此值旁边”。类型之间的区别在于是否应在存储(INSERT 或 UPDATE)或检索(SELECT 查询)期间应用任何时区。 (这种行为针对 Postgres 进行了描述——其他数据库在这方面差异很大。)
更准确地说,应该说 TIMESTAMP WITHOUT TIME ZONE 存储没有时区的日期时间值。但如果没有任何时间框架参考,任何查看该数据的人都必须假设(希望,祈祷?)这些值是 UTC。但同样,没有实际意义,因为您几乎不应该使用这种类型。
仔细阅读the doc,并进行一些实验以阐明您的理解。
未分区
如果您想存储可能时间的一般概念而不是特定时刻,请使用另一种类型,TIMESTAMP WITHOUT TIME ZONE。
例如,今年圣诞节从 2017 年 12 月 25 日的第一刻开始。那将是 2017-12-25T
00:00:00,没有时区指示,也没有与 UTC 的偏移。这个值只是关于可能时刻的一个模糊概念。在我们应用时区(或偏移量)之前,它没有任何意义。所以我们使用TIMESTAMP WITHOUT TIME ZONE 存储它。
为圣诞老人的特殊活动后勤部门工作的精灵们将时区作为他们计划过程的一部分。目前最早的时区是Pacific/Kiribati,比UTC 早14 小时。精灵们安排圣诞老人第一次到达那里。精灵们安排了一个飞行计划,将驯鹿带到其他时区,午夜过后不久,例如Pacific/Auckland。随着每个区域的午夜到来,他们继续向西行进。 Asia/Kolkata 几小时后,Europe/Paris 更晚,America/Montreal 更晚,等等。
精灵们会使用WITH TIME ZONE 记录每个具体的送达时刻,而圣诞节的一般概念将存储为WITHOUT TIME ZONE。
WITHOUT TIME ZONE 在商业应用程序中的另一个用途是安排比几周更远的约会。世界各地的政客们莫名其妙地偏爱搞乱时钟和重新定义时区规则。他们加入夏令时 (DST),离开 DST,在不同的日期开始 DST,或在不同的日期结束 DST,或者将时钟移动 15 分钟或半小时。所有这些都是土耳其、美国、俄罗斯、委内瑞拉和其他国家在过去几年中完成的。
政客们经常在没有预先警告的情况下做出这些改变。因此,如果您在 13:00 安排牙科预约六个月,则可能应存储为TIMESTAMP WITHOUT TIME ZONE,否则政客可能会将您的预约有效地更改为中午、下午 2 点或 13:30。