首页 > 解决方案 > INTERVAL '1' DAY 是否总是等于 INTERVAL '24' HOURS?

问题描述

直观地说,这两个间隔代表相同的时间量。但不同之处在于夏令时的变化,在这种情况下,“1 天”可以表示春季的“23 小时”或秋季的“25 小时”。

我用 PostgreSQL 进行了测试,这两个时间间隔并不意味着相同的时间:

set timezone TO 'CET';
SELECT timestamp with time zone'2020-03-29 0:00 Europe/Bratislava' + INTERVAL '1' DAY,
       timestamp with time zone'2020-03-29 0:00 Europe/Bratislava' + INTERVAL '24' HOUR;

返回这个:

2020-03-29T22:00:00.000Z    2020-03-29T23:00:00.000Z

客户端的时区是 UTC,这就是返回值采用 UTC 的原因。但重要的是它们并不相同。

我也尝试过使用 MySQL,但在我看来它不支持时区,只支持时区偏移。并且区域偏移没有 DST 更改,因此一天始终是 24 小时。

另一方面,支持许多 SQL 实现(如 Apache Drill、Apache Flink、Apache Beam 等)的 Apache Calcite 将间隔文字表示为 java 的BigDecimal:日-秒间隔转换为毫秒,并且假定天始终为 24 小时.

我的问题是:根据 SQL 标准,哪种方法是正确的?

编辑:

检查了更多数据库:

结论:PostgreSQL 似乎是 1 天与 24 小时不同的唯一例外。

标签: sqlapache-calcite

解决方案


我认为你的答案在于这个资源:https ://www.postgresql.org/docs/9.1/functions-datetime.html

向带时区值的时间戳添加间隔值(或从中减去间隔值)时,天数组件将带时区的时间戳的日期提前(或减少)指定的天数。在夏令时更改期间(会话时区设置为识别 DST 的时区),这意味着间隔“1 天”不一定等于间隔“24 小时”。例如,会话时区设置为 CST7CDT,时区为“2005-04-02 12:00-07”的时间戳 + 间隔“1 天”将生成时区为“2005-04-03 12:00-”的时间戳06',同时将间隔“24 小时”添加到与时区相同的初始时间戳会产生带有时区“2005-04-03 13:00-06”的时间戳,因为夏令时在 2005-04- 03 02:


推荐阅读