【问题标题】:TIMESTAMP vs TIMESTAMPTZ correct value when taking time differenceTIMESTAMP vs TIMESTAMPTZ 取时差时的正确值
【发布时间】:2018-11-03 00:20:07
【问题描述】:

对于查询:

SELECT '2018-03-01'::TIMESTAMP - '2018-09-01'::TIMESTAMP, 
       '2018-03-01'::TIMESTAMPTZ - '2018-09-01'::TIMESTAMPTZ;

返回值-184 days 对应TIMESTAMP-183 days -23:00:00 对应TIMESTAMPTZ

对我来说,-184 days“似乎”是正确的,但我总是被告知使用TIMESTAMPTZ。哪个是正确答案?

【问题讨论】:

  • Timestamptz 实际上是带有时区数据类型的时间戳,它也处理时区。它在值的末尾指定时区,如下所示:+01。亲自查看select current_date::timestamptz。数据类型的选择是根据具体情况选择的。
  • @KamilG。但是如果TIMESTAMPTZ 对每个值应用相同的时区数据,那么差异不应该是一样的吗?
  • 结果-183 days -23:00:00是正确的。请对此进行调查:select '2018-03-01'::timestamptz , '2018-09-01'::timestamptz; 可能由于夏令时的原因,时区时差为 1 小时。减去 timestamp 类型时情况并非如此,因为它不会查看跨区域和日历的时间差异。
  • @KamilG。啊,夏令时开始发挥作用。明白了。如果您发布答案,我可以接受它
  • @KamilG。我认为这与日光谚语无关SELECT '2018-03-01'::TIMESTAMP - '2018-03-20'::TIMESTAMP, '2018-03-01'::timestamptz - '2018-03-20'::timestamptz;1 hour 中仍然存在差异@

标签: postgresql timestamp


【解决方案1】:

作为对 OP 问题下评论讨论的补充而发布的答案。


数据类型timestamptz实际上是带时区的时间戳,而timestamp是不带时区的时间戳。

如下所示减去这些特定日期得到的结果是正确的,相差 1 小时

SELECT '2018-03-01'::TIMESTAMPTZ - '2018-09-01'::TIMESTAMPTZ;

这是因为2018-03-01::timestamptz+012018-09-01+02

通过此查询自己查看

SELECT '2018-03-01'::TIMESTAMPTZ, '2018-09-01'::TIMESTAMPTZ

1 小时的差异很可能来自夏令时和随时间变化的时区。


一般来说,我总是会选择在我的系统中包含时区,以正确处理世界各地的时差,并避免因没有时区而可能出现的问题。客户端和服务器可能有不同的时区,这可能会导致问题。

【讨论】:

  • timestamptz 并不是大多数人认为的那样。它不包含任何时区数据,但它确实以 UTC 格式存储数据,并根据 db-instance、db 本身或当前连接的设置“自动”向用户进行转换。
猜你喜欢
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多