I want to subtract 2 dates and represent the result in hour and minute in one decimal figure.
I have the following table and I am doing it in this way but the result is not as desired.
There is some slight variation, I'm sure this is simple arithmetic but I'm not getting it right.
select start_time, end_time, (end_time-start_time)*24 from
come_leav;
START_TIME END_TIME (END_TIME-START_TIME)*24 ------------------- ------------------- ------------------------ 21-06-2011 14:00:00 21-06-2011 16:55:00 2.9166667 21-06-2011 07:00:00 21-06-2011 16:50:00 9.8333333 21-06-2011 07:20:00 21-06-2011 16:30:00 9.1666667
I want the result (end_time-start_time) as below.
16:55- 14:00 = 2.55 16:50-07:00 = 9.5 16:30-7:20 = 9.1 and so on.
How can I do that?
SQL> edit
Wrote file afiedt.buf
1 select start_date
2 , end_date
3 , (24 * extract(day from (end_date - start_date) day(9) to second))
4 + extract(hour from (end_date - start_date) day(9) to second)
5 + ((1/100) * extract(minute from (end_date - start_date) day(9) to second)) as "HOUR.MINUTE"
6* from t
SQL> /
START_DATE END_DATE HOUR.MINUTE
------------------- ------------------- -----------
21-06-2011 14:00:00 21-06-2011 16:55:00 2.55
21-06-2011 07:00:00 21-06-2011 16:50:00 9.5
21-06-2011 07:20:00 21-06-2011 16:30:00 9.1
It should be noted for those coming across this code that the decimal portions are ACTUAL minute differences, and not part of an hour. .5
, therefore, represents 50 minutes
, not 30 minutes
.
Try this
round(to_number(end_time - start_time) * 24)
Oracle represents dates as a number of days, so (end_time-start_time)*24
gives you hours. Let's assume you have this number (eg. 2.9166667
) in h
column. Then you can easily convert it to the format you want with: FLOOR(h) + (h-FLOOR(h))/100*60
.
Example:
WITH diff AS (
SELECT (TO_DATE('21-06-2011 16:55:00', 'DD-MM-YYYY HH24:MI:SS') - TO_DATE('21-06-2011 14:00:00', 'DD-MM-YYYY HH24:MI:SS'))*24 h
FROM dual
) SELECT FLOOR(h) + (h-FLOOR(h))/100*60
FROM diff
In your case:
SELECT start_time, end_time,
FLOOR((end_time-start_time)*24) + ((end_time-start_time)*24-FLOOR((end_time-start_time)*24))/100*60 AS hours_diff
FROM come_leav
try this:
SELECT
TRIM(TO_CHAR(TRUNC(((86400*(end_time - start_time))/60)/60)-24*(trunc((((86400*(end_time - start_time))/60)/60)/24)),'00')) ||'.'||
TRIM(TO_CHAR(TRUNC((86400*(end_time - start_time))/60)-60*(trunc(((86400*(end_time - start_time))/60)/60)),'00')) ||'.' as duration
FROM come_leav;
Edit: if you need a number, then
trunc(end_date-start_date)*24+
to_number(to_char(trunc(sysdate)+(end_date-start_date),'HH24.MI'))
For string result, if delta is LESS THAN 24H: I would go with
to_char(trunc(sysdate)+(end_date-start_date),'HH24.MI')
or ...'HH24:MI:SS'
, but thats my personal preference.
for longer than 24H terms, I would prefix with
trunc(end_date-start_date)||"days "||
to_char(trunc(sysdate)+(end_date-start_date),'HH24.MI')
Yes, as oracle counts in days, with seconds precision, you are dealing with arithmetical problems. Once because you are only handling minutes (so you might round your number to trunc(days*24*60+0.5)/24/60
), but the binary arithmetic imprecision on the number 1/24/60 might still cause you troubles.
Edit2.1:
to_char(24*(trunc(end_date)-trunc(start_date))+to_number(to_char(end_date,'HH24.MI'))-to_number(to_char(start_date,'HH24.MI')),'99999.99')
But The result could be quite confusing for the average, as the decimal 7.50 would suggest seven and a half hour, or at least 7 hour 50 minutes, opposed to the elapsed time of 7 hours 10 minutes.
This query is very usefull for me and if any body want diffrence between start_date and end_date with time like HH:MI:SS please use this query.
SELECT
TRIM(TO_CHAR(TRUNC(((86400*(end_date - start_date))/60)/60)-24*(trunc((((86400(end_date - start_date))/60)/60)/24)),'00')) ||'.'||
TRIM(TO_CHAR(TRUNC((86400*(actual_completion_date - actual_start_date))/60)-60*(trunc(((86400*(end_date - start_date))/60)/60)),'00')) ||'.'||
TRIM(TO_CHAR(TRUNC((86400*(end_date - start_date)))-60*(trunc((86400*(end_date - actual_start_date))/60)),'00')) as duration
FROM fnd_concurrent_requests;
This is a very ugly way to do it, and this first part doesn't exactly question by the OP, but it gives a way to get results by subtracting 2 date fields -- in my case, the CREATED_DATE
and today represented by SYSDATE
:
SELECT FLOOR(ABS(MONTHS_BETWEEN(CREATED_DATE, SYSDATE)) / 12) || ' years, '
|| (FLOOR(ABS(MONTHS_BETWEEN(CREATED_DATE, SYSDATE))) -
(FLOOR(ABS(MONTHS_BETWEEN(CREATED_DATE, SYSDATE)) / 12)) * 12) || ' months, '
-- we take total days - years(as days) - months(as days) to get remaining days
|| FLOOR((SYSDATE - CREATED_DATE) - -- total days
(FLOOR((SYSDATE - CREATED_DATE)/365)*12)*(365/12) - -- years, as days
-- this is total months - years (as months), to get number of months,
-- then multiplied by 30.416667 to get months as days (and remove it from total days)
FLOOR(FLOOR(((SYSDATE - CREATED_DATE)/365)*12 - (FLOOR((SYSDATE - CREATED_DATE)/365)*12)) * (365/12)))
|| ' days, '
-- Here, we can just get the remainder decimal from total days minus
-- floored total days and multiply by 24
|| FLOOR(
((SYSDATE - CREATED_DATE)-(FLOOR(SYSDATE - CREATED_DATE)))*24
)
|| ' hours, '
-- Minutes just use the unfloored hours equation minus floored hours,
-- then multiply by 60
|| ROUND(
(
(
((SYSDATE - CREATED_DATE)-(FLOOR(SYSDATE - CREATED_DATE)))*24
) -
FLOOR((((SYSDATE - CREATED_DATE)-(FLOOR(SYSDATE - CREATED_DATE)))*24))
)*60
)
|| ' minutes'
AS AGE FROM MyTable`
It delivers the output as x years, x months, x days, x hours, x minutes. It could be reformatted however you like by changing the concatenated strings.
To more directly answer the question, I've gone ahead and written out how to get the total hours with minutes as hours.minutes
:
select
((FLOOR(end_date - start_date))*24)
|| '.' ||
ROUND(
(
(
((end_date - start_date)-(FLOOR(end_date - start_date)))*24
) -
FLOOR((((end_date - start_date)-(FLOOR(end_date - start_date)))*24))
)*60
)
from
come_leav;
you can work with the extract:
SELECT start_time, end_time, extract(HOUR FROM end_time-start_time) || '.' || extract(MINUTE FROM end_time-start_time)
From come_leav;
来源:https://stackoverflow.com/questions/7460266/how-to-subtract-2-dates-in-oracle-to-get-the-result-in-hour-and-minute