Reputation: 107
I am trying to come up with a way in Oracle to calculate the difference between dates in days.
In short. I have two data fields "begins_at" and "ends_at" and the DATA_TYPE for those fields is "TIMESTAMP(6)"
For example. I have the following scenario:
"begins_at" value as “26-MAR-13 02.50.00.000000000 PM”
"ends_at" value as “30-MAR-13 09.25.00.000000000 PM”
I am trying to calculate the different between the two timestamps in days. Is it possible in Oracle?
I tried the following statement but threw an error:
Select TO_DATE(begins_at, 'YYYYMMDD HH:MI:SS AM') - TO_DATE(ends_at, 'YYYYMMDD HH:MI:SS AM') day_diff
From dual
Any tip is much appreciated.
Upvotes: 1
Views: 31921
Reputation: 5792
Days, hours, minutes, seconds diff. example - copy/paste to see the output. Replace dates with your dates...:
SELECT start_date, end_date, time_diff,
EXTRACT(DAY FROM time_diff) days,
EXTRACT(HOUR FROM time_diff) hours,
EXTRACT(MINUTE FROM time_diff) minutes,
EXTRACT(SECOND FROM time_diff) seconds
FROM
(
Select start_date, end_date, (end_date - start_date) time_diff
From
(
Select CAST(to_date('01/01/2012 10:00:00 am', 'dd/mm/yyyy hh:mi:ss am') AS TIMESTAMP) end_date
, CAST(to_date('01/01/2012 07:00:00 am', 'dd/mm/yyyy hh:mi:ss am') AS TIMESTAMP) start_date
From dual
)
)
/
Subtract time only example:
SELECT trunc(mydate / 3600) hr
, trunc(mod(mydate, 3600) / 60) mnt
, trunc(mod(mydate, 3600) / 60 /60) sec
FROM
(
SELECT (to_date('01/03/2012 10:00:00', 'mm/dd/yyyy hh24:mi:ss') -
to_date('01/01/2012 07:00:00', 'mm/dd/yyyy hh24:mi:ss')) * 86400 mydate
FROM dual
)
/
HR MNT SEC
-------------
51 0 0
Upvotes: 1
Reputation: 191570
As our anonymous equine friend noted, 'threw an error' is not helpful. However, it's likely you are getting an ORA-01830, 'date format picture ends before converting entire input string', or ORA-1858, 'a non-numeric character was found where a numeric was expected', or something similar.
The to_date
function takes a char
argument, so when you pass your timestamp
field to it there is an implicit conversion happening; you're essentially doing:
to_date(to_char(begins_at, 'DD-MON-RR'), 'YYYYMMDD HH:MI:SS AM')
... only using your default NLS settings; I'm guessing you're NLS_DATE_FORMAT is set to 'DD-MON-RR' for this example; the exact value will affect the error you get. The format that your timestamp
is being given as a string does not match the format you specified for to_date
.
You should never rely on implicit conversions, but you don't need to do a conversion here at all. timestamp
values can be compared directly, and the results are explained in the documentation. Just subtracting one value form the other will give you the answer as an interval
data type:
select ends_at - begins_at from t42;
ENDS_AT-BEGINS_AT
---------------------------------------------------------------------------
+000000004 06:35:00.000000
If you just want the whole day portion you can use extract
:
select extract (day from ends_at - begins_at) from t42;
EXTRACT(DAYFROMENDS_AT-BEGINS_AT)
---------------------------------
4
You can also treat the timestamp
as date
using cast
:
select cast(ends_at as date) - cast(begins_at as date) from t42;
CAST(ENDS_ATASDATE)-CAST(BEGINS_ATASDATE)
-----------------------------------------
4.27430556
I'm not sure why you're using timestamp
at all though. The Oracle date
type includes a time portion, down to a precision of a second. As you don't (currently) seem to be using the fractional part of the timestamp, sticking to date
might make your manipulations simpler, but I guess it depends what you intend to do with these fields later.
Upvotes: 7
Reputation: 10573
Try something like this:
SELECT TO_DATE('20120125 11:00:00 AM', 'YYYYMMDD HH:MI:SS AM')
- TO_DATE('20120120 10:00:00 AM', 'YYYYMMDD HH:MI:SS AM') day_diff
FROM dual
You can refer this. It will really help you
Upvotes: 1
Reputation: 7899
See http://docs.oracle.com/cd/E17952_01/refman-5.1-en/date-and-time-functions.html#function_datediff. It describes DATEDIFF
, which returns the difference in days, treating only the date values.
Upvotes: 1