我们正在尝试对日期进行算术运算。我们正尝试增加1天(24小时),这是一个基本示例...
select to_date('2018-10-06 22:00:00') + 1 from dual;
我们从中得到的结果如下...
2018-10-07 22:00:00
从表面上看,这看起来不错,但是我们处于悉尼时区,并且在那个过渡时期出现了夏令时,所以时间应该更像这样……
2018-10-07 23:00:00
所以我想我的问题是,在oracle中进行算术运算时是否可以考虑夏令时。一个想法是将初始日期转换为UTC并转换回悉尼时间,但这似乎是一个复杂的解决方案,可能已经由某处的oracle功能处理了。
欢呼
答案 0 :(得分:2)
您实际上不能直接用日期来完成操作,因为这些日期不支持时区。
您可以从带有时区的时间戳开始,例如作为时间戳文字:
select timestamp '2018-10-06 22:00:00 Australia/Sydney' + interval '1' day
from dual;
TIMESTAMP'2018-10-0622:00:00AUSTRALIA/SYDNEY'+
----------------------------------------------
2018-10-07 23:00:00.000000000 AUSTRALIA/SYDNEY
如果您要舍弃该信息,可以将其回溯到日期:
select cast(timestamp '2018-10-06 22:00:00 Australia/Sydney' + interval '1' day as date)
from dual;
CAST(TIMESTAMP'2018
-------------------
2018-10-07 23:00:00
如果您从某个日期开始,例如在表格列中,您可以将其强制转换为时间戳并指定时区:
with your_table (your_date) as (
select to_date('2018-10-06 22:00:00') from dual
)
select from_tz(cast(your_date as timestamp), 'Australia/Sydney') + interval '1' day
from your_table;
FROM_TZ(CAST(YOUR_DATEASTIMESTAMP),'AUSTRALIA/
----------------------------------------------
2018-10-07 23:00:00.000000000 AUSTRALIA/SYDNEY
,并且有选择地再次回溯到日期,以丢弃小数秒和时区信息。
如果您的会话时区是悉尼,那么可以通过强制转换为timestamp with time zone
来隐式设置该时间:
with your_table (your_date) as (
select to_date('2018-10-06 22:00:00') from dual
)
select cast(your_date as timestamp with time zone) + interval '1' day
from your_table;
但是通常最好不要假设任何会运行代码的会话环境。
当时钟在DST结束时返回时,您可以通过包含DST指示器来指定02:00到03:00之间两个可能的时间值中的哪个:
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZH:TZM';
select timestamp '2018-04-01 01:00:00 Australia/Sydney AEDT' from dual;
TIMESTAMP'2018-04-0101:00:
--------------------------
2018-04-01 01:00:00 +11:00
select timestamp '2018-04-01 02:00:00 Australia/Sydney AEDT' from dual;
TIMESTAMP'2018-04-0102:00:
--------------------------
2018-04-01 02:00:00 +11:00
select timestamp '2018-04-02 02:00:00 Australia/Sydney AEST' from dual;
TIMESTAMP'2018-04-0202:00:
--------------------------
2018-04-02 02:00:00 +10:00
select timestamp '2018-04-01 03:00:00 Australia/Sydney AEST' from dual;
TIMESTAMP'2018-04-0103:00:
--------------------------
2018-04-01 03:00:00 +10:00
尽管对我来说,这似乎仅在12.2.0.1中有效;在早期版本中,无法识别AEST / AEDT(尽管EST是)。我不确定这是否只是时区文件的版本-我的12.2实例的版本是26。
如果在DST开始时时钟前进时,如果您所看到的时间似乎不存在于小时中,那么可以采用其他方法,因为它们无效,因此您无能为力。如果使用sysdate
填充字段,并且服务器设置为Sydney或current_date且会话设置为,则不会发生这种情况。使用to_date()
创建的日期可能在该窗口中,但是您可能需要弄清楚原因并停止这种情况。