Calculate difference between 2 date / times in Oracle SQL
Asked Answered
T

22

108

I have a table as follows:

Filename - varchar
Creation Date - Date format dd/mm/yyyy hh24:mi:ss
Oldest cdr date - Date format dd/mm/yyyy hh24:mi:ss

How can I calcuate the difference in hours minutes and seconds (and possibly days) between the two dates in Oracle SQL?

Thanks

Tryst answered 8/7, 2009 at 8:39 Comment(1)
Near-duplicate: #9323435Pneumo
R
141

You can substract dates in Oracle. This will give you the difference in days. Multiply by 24 to get hours, and so on.

SQL> select oldest - creation from my_table;

If your date is stored as character data, you have to convert it to a date type first.

SQL> select 24 * (to_date('2009-07-07 22:00', 'YYYY-MM-DD hh24:mi') 
             - to_date('2009-07-07 19:30', 'YYYY-MM-DD hh24:mi')) diff_hours 
       from dual;

DIFF_HOURS
----------
       2.5

Note:

This answer applies to dates represented by the Oracle data type DATE. Oracle also has a data type TIMESTAMP, which can also represent a date (with time). If you subtract TIMESTAMP values, you get an INTERVAL; to extract numeric values, use the EXTRACT function.

Rienzi answered 8/7, 2009 at 8:44 Comment(4)
Has there been a change in Oracle's behavior at some point? When I subtract one date from another I get an INTERVAL data type, not a simple float.Pneumo
@JonofAllTrades: No, when you subtract values of type DATE, you get the number of days (as a NUMBER). However, if you subtract TIMESTAMP values, you get INTERVALDS. Probably you are working with TIMESTAMP and not DATE values. I edited the answer.Thrips
Regarding your note - Both the DATE and TIMESTAMP data types have a time (hours, minutes and seconds) component. TIMESTAMP also has a fractional seconds time component (and potentially time zone components).Extensor
"This will give you the difference in days." Can you link to Oracle documentation please?Beautician
C
26

To get result in seconds:

select (END_DT - START_DT)*60*60*24 from MY_TABLE;

Check [https://community.oracle.com/thread/2145099?tstart=0][1]

Connotative answered 29/10, 2015 at 18:30 Comment(0)
K
19
select 
    extract( day from diff ) Days, 
    extract( hour from diff ) Hours, 
    extract( minute from diff ) Minutes 
from (
        select (CAST(creationdate as timestamp) - CAST(oldcreationdate as timestamp)) diff   
        from [TableName] 
     );

This will give you three columns as Days, Hours and Minutes.

Karakalpak answered 27/11, 2014 at 9:18 Comment(0)
A
16
declare
strTime1 varchar2(50) := '02/08/2013 01:09:42 PM';
strTime2 varchar2(50) := '02/08/2013 11:09:00 PM';
v_date1 date := to_date(strTime1,'DD/MM/YYYY HH:MI:SS PM');
v_date2 date := to_date(strTime2,'DD/MM/YYYY HH:MI:SS PM');
difrence_In_Hours number;
difrence_In_minutes number;
difrence_In_seconds number;
begin
    difrence_In_Hours   := (v_date2 - v_date1) * 24;
    difrence_In_minutes := difrence_In_Hours * 60;
    difrence_In_seconds := difrence_In_minutes * 60;

    dbms_output.put_line(strTime1);        
    dbms_output.put_line(strTime2);
    dbms_output.put_line('*******');
    dbms_output.put_line('difrence_In_Hours  : ' || difrence_In_Hours);
    dbms_output.put_line('difrence_In_minutes: ' || difrence_In_minutes);
    dbms_output.put_line('difrence_In_seconds: ' || difrence_In_seconds);        
end ;

Hope this helps.

Aspic answered 9/2, 2013 at 10:46 Comment(0)
O
9

You may also try this:

select to_char(to_date('1970-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')+(end_date - start_date),'hh24:mi:ss')
       as run_time from some_table;

It displays time in more human readable form, like: 00:01:34. If you need also days you may simply add DD to last formatting string.

Orientation answered 30/1, 2015 at 9:27 Comment(0)
O
7

Calculate age from HIREDATE to system date of your computer

SELECT HIREDATE||'        '||SYSDATE||'       ' ||
TRUNC(MONTHS_BETWEEN(SYSDATE,HIREDATE)/12) ||' YEARS '||
TRUNC((MONTHS_BETWEEN(SYSDATE,HIREDATE))-(TRUNC(MONTHS_BETWEEN(SYSDATE,HIREDATE)/12)*12))||
'MONTHS' AS "AGE  "  FROM EMP;
Otiliaotina answered 7/10, 2012 at 12:56 Comment(0)
M
6

You could use to_timestamp function to convert the dates to timestamps and perform a substract operation.

Something like:

SELECT 
TO_TIMESTAMP ('13.10.1990 00:00:00','DD.MM.YYYY HH24:MI:SS')  - 
TO_TIMESTAMP ('01.01.1990:00:10:00','DD.MM.YYYY:HH24:MI:SS')
FROM DUAL
Marlinemarlinespike answered 8/7, 2009 at 9:24 Comment(3)
I have tried both the to_date and to_timestamp and both give me an answer in days, rounded down so if the difference is 1 hour I receive an answer of 0, multiplying this by 24 gives 0. I do receive the correct answer if I type in the date time but I can't do this for 25m rows. Any thoughts?Tryst
Using a substraction between timestamps it would return you another timestamp in a format like "DAYS HOUR:MINS:SECS.milisecs". You could trunc this to get the value you needMarlinemarlinespike
Subtraction between timestamps returns an INTERVAL datatype. You can use the EXTRACT function to return various parts of an interval eg select extract(hour from (timestamp '2009-12-31 14:00:00' - timestamp '2009-12-31 12:15:00')) hr from dual; Note: That only shows the HOUR part, so if the difference is 1 day and 1 hour, this will show 1 not 25.Cerelly
C
4

In oracle 11g

SELECT end_date - start_date AS day_diff FROM tablexxx
suppose the starT_date end_date is define in the tablexxx
Chak answered 7/10, 2015 at 17:4 Comment(0)
B
3
select days||' '|| time from (
SELECT to_number( to_char(to_date('1','J') +
    (CLOSED_DATE - CREATED_DATE), 'J') - 1)  days,
   to_char(to_date('00:00:00','HH24:MI:SS') +
      (CLOSED_DATE - CREATED_DATE), 'HH24:MI:SS') time
 FROM  request  where REQUEST_ID=158761088 );
Briar answered 3/4, 2014 at 6:26 Comment(0)
T
2

If you want something that looks a bit simpler, try this for finding events in a table which occurred in the past 1 minute:

With this entry you can fiddle with the decimal values till you get the minute value that you want. The value .0007 happens to be 1 minute as far as the sysdate significant digits are concerned. You can use multiples of that to get any other value that you want:

select (sysdate - (sysdate - .0007)) * 1440 from dual;

Result is 1 (minute)

Then it is a simple matter to check for

select * from my_table where (sysdate - transdate) < .00071;
Tamberg answered 29/8, 2016 at 15:0 Comment(0)
C
2

If you select two dates from 'your_table' and want too see the result as a single column output (eg. 'days - hh:mm:ss') you could use something like this. First you could calculate the interval between these two dates and after that export all the data you need from that interval:

         select     extract (day from numtodsinterval (second_date
                                                   - add_months (created_date,
                                                                 floor (months_between (second_date,created_date))),
                                                   'day'))
             || ' days - '
             || extract (hour from numtodsinterval (second_date
                                                    - add_months (created_date,
                                                                  floor (months_between (second_date,created_date))),
                                                    'day'))
             || ':'
             || extract (minute from numtodsinterval (second_date
                                                      - add_months (created_date,
                                                                    floor (months_between (second_date, created_date))),
                                                      'day'))
             || ':'
             || extract (second from numtodsinterval (second_date
                                                      - add_months (created_date,
                                                                    floor (months_between (second_date, created_date))),
                                                      'day'))
     from    your_table

And that should give you result like this: 0 days - 1:14:55

Colpin answered 5/6, 2018 at 8:8 Comment(0)
G
1
select (floor(((DATE2-DATE1)*24*60*60)/3600)|| ' : ' ||floor((((DATE2-DATE1)*24*60*60) -floor(((DATE2-DATE1)*24*60*60)/3600)*3600)/60)|| '  ' ) as time_difference from TABLE1 
Gerdi answered 28/7, 2014 at 12:38 Comment(0)
B
1
(TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi'))*60*60*24 sum_seconds,
         (TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi'))*60*24 sum_minutes,
         (TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi'))*24 sum_hours,
         (TO_DATE(:P_comapre_date_1, 'dd-mm-yyyy hh24:mi') - TO_DATE(:P_comapre_date_2, 'dd-mm-yyyy hh24:mi')) sum_days 
Baeda answered 25/10, 2016 at 7:28 Comment(0)
W
1

If You want get date defer from using table and column.

SELECT TO_DATE( TO_CHAR(COLUMN_NAME_1, 'YYYY-MM-DD'), 'YYYY-MM-DD') - 
       TO_DATE(TO_CHAR(COLUMN_NAME_2, 'YYYY-MM-DD') , 'YYYY-MM-DD')  AS DATEDIFF       
FROM TABLE_NAME;
Wriest answered 21/8, 2019 at 3:59 Comment(1)
Why do you convert the dates to ISO strings only to immediately convert them back to dates? That's totally unnecessary.Maihem
L
1
select to_char(actual_start_date,'DD-MON-YYYY hh24:mi:ss') start_time,
to_char(actual_completion_date,'DD-MON-YYYY hh24:mi:ss') end_time,
floor((actual_completion_date-actual_start_date)*24*60)||'.'||round(mod((actual_completion_date-actual_start_date)*24*60*60,60)) diff_time
from fnd_concurrent_requests 
order by request_id desc;  
Lawrenson answered 24/11, 2019 at 10:2 Comment(0)
B
0

This will count time between to dates:

SELECT
  (TO_CHAR( TRUNC (ROUND(((sysdate+1) - sysdate)*24,2))*60,'999999')
  +
  TO_CHAR(((((sysdate+1)-sysdate)*24)- TRUNC(ROUND(((sysdate+1) - sysdate)*24,2)))/100*60 *100, '09'))/60
FROM dual
Barleycorn answered 28/9, 2013 at 6:30 Comment(0)
T
0

Here's another option:

with tbl_demo AS
    (SELECT TO_DATE('11/26/2013 13:18:50', 'MM/DD/YYYY HH24:MI:SS') dt1
   , TO_DATE('11/28/2013 21:59:12', 'MM/DD/YYYY HH24:MI:SS') dt2 
     FROM dual)
SELECT dt1
     , dt2
     , round(dt2 - dt1,2) diff_days
     , round(dt2 - dt1,2)*24 diff_hrs
     , numtodsinterval((dt2 - dt1),'day') diff_dd_hh_mm_ss
  from tbl_demo;
Tafoya answered 14/2, 2014 at 9:9 Comment(0)
I
0

select round( (tbl.Todate - tbl.fromDate) * 24 * 60 * 60 ) from table tbl

Insatiate answered 19/2, 2021 at 5:4 Comment(0)
M
0

for oracle sql I justbn did this and works perfect :

SELECT trunc(date_col_1) -  trunc(date_col_2) 
FROM   TABLE;
Maighdiln answered 22/11, 2022 at 13:16 Comment(0)
S
0
SQL> select
  2    numtodsinterval(
  3      to_date('2024-05-04 03:02:01', 'yyyy-mm-dd hh24:mi:ss') - to_date('2024-05-03 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
  4      , 'DAY') as diff_interval
  5  from dual
  6  ;

DIFF_INTERVAL
---------------------------------------
+000000001 03:02:01.000000000

SQL> 
Saltwort answered 5/2 at 19:45 Comment(0)
A
-1
$sql="select bsp_bp,user_name,status,
to_char(ins_date,'dd/mm/yyyy hh12:mi:ss AM'),
to_char(pickup_date,'dd/mm/yyyy hh12:mi:ss AM'),
trunc((pickup_date-ins_date)*24*60*60,2),message,status_message 
from valid_bsp_req where id >= '$id'"; 
Anvers answered 18/8, 2009 at 11:21 Comment(0)
K
-1

Single query that will return time difference of two timestamp columns:

select INS_TS, MAIL_SENT_TS, extract( hour from (INS_TS - MAIL_SENT_TS) ) timeDiff 
from MAIL_NOTIFICATIONS;
Kory answered 12/6, 2019 at 17:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.