甲骨文:计算时间戳与时区之间的差异,考虑夏令时(DST)

Oracle: calculate difference between timestamps with time zones, taking daylight saving time (DST) into account

2022 年 3 月 27 日 02:00,在时区 +01:00,时钟快进一小时。所以我希望基于以下代码,v_date_diff 将是 +00000 03:00:00。然而它是:+00000 04:00:00.

v_start_date          TIMESTAMP WITH TIME ZONE := TO_TIMESTAMP_TZ ('27/03/2022 00:59:59 +1:00', 'DD/MM/YYYY HH24:MI:SS TZH:TZM');
v_end_date            TIMESTAMP WITH TIME ZONE := TO_TIMESTAMP_TZ ('27/03/2022 04:59:59 +1:00', 'DD/MM/YYYY HH24:MI:SS TZH:TZM');
v_date_diff           INTERVAL DAY(5) TO SECOND(0) := v_end_date - v_start_date;

这是为什么?我该如何解决?

UTC 不遵循夏令时,因此与夏令时的任何固定偏移都不会遵循夏令时。所以 Oracle 是正确的,你的时间戳之间有 4 个小时。

如果您使用实际遵守夏令时的时区指定时间戳,您将得到所需的 3 小时结果。例如,时区“Europe/Berlin”遵守夏令时,因此以下代码returns 相差 3 小时

declare 
  v_start_date          TIMESTAMP WITH TIME ZONE := TO_TIMESTAMP_TZ ('27/03/2022 00:59:59 Europe/Berlin', 
                                                                     'DD/MM/YYYY HH24:MI:SS TZR');
  v_end_date            TIMESTAMP WITH TIME ZONE := TO_TIMESTAMP_TZ ('27/03/2022 04:59:59 Europe/Berlin', 
                                                                     'DD/MM/YYYY HH24:MI:SS TZR');
  v_date_diff           INTERVAL DAY(5) TO SECOND(0) := v_end_date - v_start_date;
begin
  dbms_output.put_line( v_date_diff );
end;

Oracle 数据库以 UTC 时间执行所有时间戳算法。 +1:00 表示 UTC 前 1 小时 - 始终,即它不应用任何 Daylight-Saving-Times。以阿尔及利亚为例,它也有时区 +1:00 但不使用 Daylight-Saving-Times.

当你说“2022 年 3 月 27 日 02:00,在时区 +01:00 时钟向前一小时。”那么你的数据是错误的.在这种情况下,它必须是(使用 TIMESTAMP 文字)

v_end_date   TIMESTAMP WITH TIME ZONE := TIMESTAMP '2022-03-27 04:59:59 +2:00';

那么相差3个小时。或者使用 Justin Cave 建议的时区区域名称(例如 Europe/Berlin)。