SYSTIMESTAMP INTERVAL Processing

本文介绍了一种更高效且直观的方法来处理Oracle数据库中的日期和时间调整,通过使用INTERVAL函数替代传统的时间分数计算,避免了类型转换带来的精度损失和潜在错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

This is just a quick post to try to encourage the use of the INTERVAL function when adjusting (sys)timestamps (or dates). I thought this would be better expressed through a quick script with comments to show how using the traditional Oracle method of calculating fractions of a day can cause problems and make you have to think more than necessary.

There are 2 main issues with using the traditional Oracle method of calculating date/time changes. Firstly, it’s strange. You have to calculate fractions of a day. 1 second is 1/86400, 1 minute is 1/1440 [maybe 1/(24*60) expresses it better]. Secondly, with timestamps it causes an implicit conversion to a date type, with all of the unintended consequences that implicit conversion carries.

Lets run the script and see what happens:

Script Output


> -- Lets just set the date format explicitly before we start.
> alter session set nls_date_format = 'DD-MON-YYYY HH24:MI:SS'
session SET altered.


> -- Lets start simple and add a day.
> select systimestamp, systimestamp + 1 from dual


SYSTIMESTAMP  SYSTIMESTAMP+1            
------------- ------------------------- 
09-DEC-11 18.39.53.026000000 +00:00 10-DEC-2011 18:39:53  


> -- Hang on, doing this the traditional Oracle way has implicitly cast
> -- the timestamp into a sysdate format. We need to convert it back.
> -- Lets try that again, but add 3 hours instead
> select systimestamp, to_timestamp(
>        systimestamp + (3/24),
>       'DD-MON-YYYY HH24:MI:SS' ) from dual


SYSTIMESTAMP  TO_TIMESTAMP(SYSTIMESTAMP+(3/24),'DD-MON-YYYYHH24:MI:SS') 
------------- ------------------------- 
09-DEC-11 18.39.53.026000000 +00:00 09-DEC-11 21.39.53.000000000 


> -- So we have an implicit conversion, and we've lost the timestamp precision.
> -- Now lets add 3 hours, 5 minutes 10.5 seconds.
>select systimestamp, to_timestamp(
>       systimestamp + (3/24) + (5/(24*60)) + (10.5/24/60/60),
>      'DD-MON-YYYY HH24:MI:SS') from dual 


 SYSTIMESTAMP  TO_TIMESTAMP(SYSTIMESTAMP+(3/24)+(5/(24*60))+(10.5/24/60/60),'DD-MON-YYYYHH24:MI:SS') 
------------- ------------------------- 
09-DEC-11 18.39.53.026000000 +00:00 09-DEC-11 21.45.04.000000000 


> -- And we completely lost the .5 in the 10.5 as we've converted to a sysdate.
> -- It was rounded up. You might also have noticed that I have used some
> -- different date processing to calculate fractions of a day.
> -- There are many different way to calculate time in Oracle:
> -- 10 minutes can be 10/1440, 10/60/24, 10/(60*24), 0.00694, 600/86400 etc,
> -- It's all tricky to understand and standards vary from company to company,
> -- if the company actually has a standard.
> -- There is a better way, using the INTERVAL function. It goes like this:
> -- Lets start simple and add a day.


> select systimestamp, systimestamp + INTERVAL '1' day from dual


SYSTIMESTAMP  SYSTIMESTAMP+INTERVAL'1'DAY 
------------- --------------------------- 
09-DEC-11 18.39.53.042000000 +00:00 10-DEC-11 18.39.53.042000000 +00:00 


> -- So far so good. And we haven't lost the data type either!
> -- No implicit conversion to break our code in the future.
> -- Now lets try to add 3 hours


> select systimestamp, systimestamp + INTERVAL '3' hour from dual


SYSTIMESTAMP  SYSTIMESTAMP+INTERVAL'3'HOUR 
------------- ---------------------------- 
09-DEC-11 18.39.53.042000000 +00:00 09-DEC-11 21.39.53.042000000 +00:00 


> -- Note the indicator is always singular.
> -- Now lets add 3 hours, 5 minutes 10.5 seconds


> select systimestamp, 
>        systimestamp + INTERVAL '3' hour
>                     + INTERVAL '5' minute
>                     + INTERVAL '10.5' second
>        from dual 


SYSTIMESTAMP  SYSTIMESTAMP+INTERVAL'3'HOUR+INTERVAL'5'MINUTE+INTERVAL'10.5'SECOND
------------- ------------------------------------------------------------------- 
09-DEC-11 18.39.53.042000000 +00:00 09-DEC-11 21.45.03.542000000 +00:00                                 


> -- Spot on - and the precision is correct too
> -- My mam/mum/mom* could read it and work out what was going on.
> -- But she is an OCA** (* delete as applicable) (**not really)
> -- There you go. Get your company to use this nomenclature and you're home free.
> -- No more strange time-base calculations or implicit conversion errors.
> -- It also works with DATE types too.


Original Script
set echo on 


-- Lets just set the date format explicitly before we start.
alter session set nls_date_format = 'DD-MON-YYYY HH24:MI:SS';

-- Lets start simple and add a day.
select systimestamp, systimestamp + 1 from dual;

-- Hang on, doing this the traditional Oracle way has implicitly cast
-- the timestamp into a sysdate format. We need to convert it back.
-- Lets try that again, but add 3 hours instead
select systimestamp, to_timestamp(
       systimestamp + (3/24),
                                   'DD-MON-YYYY HH24:MI:SS' ) from dual; 

-- So we have an implicit conversion, and we've lost the timestamp precision.

-- Now lets add 3 hours, 5 minutes 10.5 seconds.
select systimestamp, to_timestamp(
       systimestamp + (3/24) + (5/(24*60)) + (10.5/24/60/60),
                                   'DD-MON-YYYY HH24:MI:SS') from dual;

-- And we completely lost the .5 in the 10.5 as we've converted to a sysdate.
-- It was rounded up. You might also have noticed that I have used some
-- different date processing to calculate fractions of a day.
-- There are many different way to calculate time in Oracle:
-- 10 minutes can be 10/1440, 10/60/24, 10/(60*24), 0.00694, 600/86400 etc,
-- It's all tricky to understand and standards vary from company to company,
-- if the company actually has a standard.

-- There is a better way, using the INTERVAL function. It goes like this:
-- Lets start simple and add a day.
select systimestamp, systimestamp + INTERVAL '1' day from dual; 

-- So far so good. And we haven't lost the data type either!
-- No implicit conversion to break our code in the future.
-- Now let's try to add 3 hours
select systimestamp, systimestamp + INTERVAL '3' hour from dual;

-- Note the indicator is always singular.
-- Now lets add 3 hours, 5 minutes 10.5 seconds
select systimestamp, systimestamp + INTERVAL '3' hour
                                  + INTERVAL '5' minute
                                  + INTERVAL '10.5' second
                     from dual;

-- Spot on - and the precision is correct too
-- My mam/mum/mom* could read it and work out what was going on.
-- But she is an OCA** (* delete as applicable) (**not really)
-- There you go. Get your company to use this nomenclature and you're home free.
-- No more strange time-base calculations or implicit conversion errors.
-- It also works with DATE types too.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值