Time difference of hours and minutes [closed] - oracle

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to find out the time difference in hours and minutes but getting error, Please help to find out the query , For example I need answer of below in oracle
16:55- 14:00 = 2:55

Convert the times to a DATE or TIMESTAMP and then subtract one from the other to get an INTERVAL DAY TO SECOND data type; then use EXTRACT to get the hour and minute components and format them:
SELECT start_time,
end_time,
TO_CHAR( EXTRACT( HOUR FROM difference ), 'FM00' )
|| ':'
|| TO_CHAR( ABS( EXTRACT( MINUTE FROM DIFFERENCE ) ), 'FM00' )
AS difference
FROM (
SELECT start_time,
end_time,
( TO_DATE( end_time, 'HH24:MI' ) - TO_DATE( start_time, 'HH24:MI' ) ) DAY TO SECOND
AS difference
FROM test_data
)
Which, for the test data:
CREATE TABLE test_data ( start_time, end_time ) AS
SELECT '14:00', '16:55' FROM DUAL UNION ALL
SELECT '14:50', '15:23' FROM DUAL UNION ALL
SELECT '16:00', '14:00' FROM DUAL UNION ALL
SELECT '16:00', '14:20' FROM DUAL UNION ALL
SELECT '00:00', '23:59' FROM DUAL;
Outputs:
START_TIME | END_TIME | DIFFERENCE
:--------- | :------- | :---------
14:00 | 16:55 | 02:55
14:50 | 15:23 | 00:33
16:00 | 14:00 | -02:00
16:00 | 14:20 | -01:40
00:00 | 23:59 | 23:59
db<>fiddle here

Please see below
SELECT
substr(
to_char(TO_TIMESTAMP ('16:55', 'HH24:MI') -
TO_TIMESTAMP ('14:00', 'HH24:MI'),
'HH24:MI')
,12
,5) "Hours"
FROM
DUAL;
SELECT
to_number(substr(
to_char(TO_TIMESTAMP ('16:55', 'HH24:MI') -
TO_TIMESTAMP ('14:00', 'HH24:MI'),
'HH24:MI')
,12
,2))
+
to_number(substr(
to_char(TO_TIMESTAMP ('16:55', 'HH24:MI') -
TO_TIMESTAMP ('14:00', 'HH24:MI'),
'HH24:MI')
,15
,2))/60 "Decimal Hours"
FROM
DUAL;
Output
Hours
-----
02:55
Decimal Hours
-------------
2.91666667

Assuming that your two times are strings, you can use a query like the one below to calculate the difference between the times. By casting time strings to dates, you can then subtract them from each other and convert the result into the format that you want.
Query
WITH
times (start_time, end_time)
AS
(SELECT '14:00', '16:55' FROM DUAL
UNION ALL
SELECT '5:00', '3:00' FROM DUAL
UNION ALL
SELECT '7:00', '23:45' FROM DUAL
UNION ALL
SELECT '15:00', '03:20' FROM DUAL)
SELECT start_time,
end_time,
TRUNC (
( TO_DATE ('1-JAN-2000 ' || end_time, 'DD-MON-YYYY HH24:MI')
- TO_DATE ('1-JAN-2000 ' || start_time, 'DD-MON-YYYY HH24:MI'))
* 24)
|| ':'
|| RPAD (
ABS (
TRUNC (
( ( ( TO_DATE ('1-JAN-2000 ' || end_time, 'DD-MON-YYYY HH24:MI')
- TO_DATE ('1-JAN-2000 ' || start_time, 'DD-MON-YYYY HH24:MI'))
* 24)
- TRUNC (
( TO_DATE ('1-JAN-2000 ' || end_time, 'DD-MON-YYYY HH24:MI')
- TO_DATE ('1-JAN-2000 ' || start_time, 'DD-MON-YYYY HH24:MI'))
* 24))
* 60)),
2,
'0') AS difference
FROM times;
Result
START_TIME END_TIME DIFFERENCE
_____________ ___________ _____________
14:00 16:55 2:55
5:00 3:00 -2:00
7:00 23:45 16:45
15:00 03:20 -11:40

Related

How to get the date difference between start date and end date in oracle as hours and minutes

I have a scenario in which for example,my start_date ='12-SEP-2018 00:01:00' and End_date ='13-SEP-2018 14:55:00' . The difference between the 2 dates must be found out in Hours and minutes like'12:20'. This must be achieved in oracle database. I tried using the following logic :
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;
I was able to get the hour difference but unable to get minutes along with it.
CREATE TABLE table_name ( start_date DATE, end_date DATE );
INSERT INTO table_name VALUES ( TIMESTAMP '2009-07-07 19:30:00', TIMESTAMP '2009-07-07 22:00:00' );
Then you can subtract one from the other and cast it to a DAY TO SECOND interval and then just EXTRACT the component parts of the time:
SELECT EXTRACT( DAY FROM difference ) AS days,
EXTRACT( HOUR FROM difference ) AS hours,
EXTRACT( MINUTE FROM difference ) AS minutes,
EXTRACT( SECOND FROM difference ) AS seconds
FROM (
SELECT ( end_date - start_date ) DAY TO SECOND AS difference
FROM table_name
);
Outputs:
DAYS | HOURS | MINUTES | SECONDS
---: | ----: | ------: | ------:
0 | 2 | 30 | 0
or you can use arithmetic to calculate the values:
SELECT TRUNC( 24 * ( end_date - start_date ) ) AS hours,
TRUNC( MOD( 24 * 60 * ( end_date - start_date ), 60 ) ) AS minutes,
ROUND( MOD( 24 * 60 * 60 * ( end_date - start_date ), 60 ) ) AS seconds
FROM table_name;
which outputs:
HOURS | MINUTES | SECONDS
----: | ------: | ------:
2 | 30 | 0
db<>fiddle here
Since you want a string value, an alternative based on your query attempt is to add the difference between your two date values (which is a numeric value, the number of days between them, including fractional days) to an arbitrary fixed date; and then convert the result of that to a string:
SELECT to_char(date '0001-01-01'
+ (to_date('2009-07-07 22:00', 'YYYY-MM-DD hh24:mi') - to_date( '2009-07-07 19:30', 'YYYY-MM-DD hh24:mi')),
'HH24:MI') as diff
FROM dual;
DIFF
-----
02:30
If the difference can exceed 24 hours then you need to decide how to report that; if you want to include days as a separate figure then you can still use this approach, but need to subtract one (if your fixed date is the first) from the difference before formatting as a string:
SELECT to_char(date '0001-01-01'
+ (to_date('2009-07-08 22:00', 'YYYY-MM-DD hh24:mi') - to_date( '2009-07-07 19:30', 'YYYY-MM-DD hh24:mi'))
- 1,
'DDD:HH24:MI') as diff
FROM dual;
DIFF
---------
001:02:30
If you want the 'hours' value to be higher instead - e.g. '26:30' in this example - then it gets rather more complicated; I see #MTO has added the 'arithmetic' approach already so I won't repeat that. But then might be better off going down the extract() route (which you should consider anyway as it's more flexible and elegant...)

calculate the running total over the column contain date difference in HH:MI:SS format in oracle

I have to find the running total over the column interval.
SELECT
( ( EXTRACT(DAY FROM intrvl) * 24 ) + ( EXTRACT(HOUR FROM intrvl) ) ) ||':'||
EXTRACT(MINUTE FROM intrvl) ||':'||
EXTRACT(SECOND FROM intrvl) ||':'|| as interval
FROM
(
SELECT
( to_timestamp(TO_CHAR(date_column_name,'dd-mon-rrrr hh:mi:ss') ) ) - ( to_timestamp(TO_CHAR(date_column_name,'dd-mon-rrrr hh:mi:ss') ) ) intrvl
FROM
dual
);
currrently Interval column of table has below data:
Interval(HH:mi:ss)
0:4:23
696:1:36
696:4:51
8760:1:18
The best I can come up with is this. Note that the interval data type does not take a format model for displaying - you can't force an interval of 25 hours to be displayed as 25:00:00 (although you can use that to INPUT an interval). Instead, it will be shown as 01 01:00:00 (meaning, a day and an hour).
with
tbl (interv) as (
select interval '0:4:23' hour(9) to second from dual union all
select interval '696:1:36' hour(9) to second from dual union all
select interval '696:4:51' hour(9) to second from dual union all
select interval '8760:1:18' hour(9) to second from dual
)
select interval '1' day * sum(date '2000-01-01' + interv - date'2000-01-01')
as sum_interv
from tbl;
SUM_INTERV
--------------------
+423 00:12:08.000000
In your original attempt you were trying to get a STRING output. I am not sure that's wise, but if that's what you need you can do it like so:
with
tbl (interv) as (
select interval '0:4:23' hour(9) to second from dual union all
select interval '696:1:36' hour(9) to second from dual union all
select interval '696:4:51' hour(9) to second from dual union all
select interval '8760:1:18' hour(9) to second from dual
)
, prep (sum_interv) as (
select interval '1' day * sum(date '2000-01-01' + interv - date'2000-01-01')
from tbl
)
select to_char( extract(day from sum_interv) * 24
+ extract(hour from sum_interv), 'fm999999999' ) || ':' ||
to_char( extract(minute from sum_interv), 'fm00' ) || ':' ||
to_char( extract(second from sum_interv), 'fm00' ) as sum_interv
from prep
;
SUM_INTERV
------------------
10152:12:08

Decoding and Converting VARCHAR Time in Oracle

I need to query particular column in DB w/c is described as VARCHAR that I need to convert into Time Format (HH:MM) and then decode to its range value, to explain further... The column stores data when (time) a particular deal was made w/in the day and instead of returning the exact time it should return the time range it was done.
Col_1 is VARCHAR2(6)
select col_2, col_1 from table
Col_2 || Col_1
A || 9:56
B || 10:03
C || 21:53
My desired Output would be
Col_2 || Col_1
A || (09:00 - 10:00)
B || (10:00 - 11:00)
C || (2100 - 2200)
Really appreciate all your comments, as I'm stuck playing with this part for a couple of days now and its giving me nightmares, sorry I'm new to DB Oracle SQL stuff and still learning. :)
Like this?
In your output, 2100 - 2200 is not consistent with the rest; I ignored it.
What should happen when the input is like 10:00 even? That is in both 9:00-10:00 and in 10:00-11:00; I assumed you want the latter.
Finally, is 00:00 ok, or do you want that to be 24:00 instead (if it is at the end) - see the second example in my output.
with input_strings ( str ) as (
select '9:49' from dual union all
select '23:00' from dual
),
prep ( dt ) as (
select trunc(to_date(str, 'hh24:mi'),'hh') from input_strings
)
select to_char(dt, 'hh24:mi') || ' - ' || to_char(dt + 1/24, 'hh24:mi') as range
from prep;
RANGE
-------------
09:00 - 10:00
23:00 - 00:00
If you do to_date(col_1, 'HH24:MI') you'll get that tie on the first day of the month, as that what Oracle defaults to with no date specified. You can then truncate that to the hour, zeroing the minutes:
with t (col_2, col_1) as (
select 'A', '9:56' from dual
union all select 'B', '10:03' from dual
union all select 'C', '21:53' from dual
)
select col_2,
to_char(to_date(col_1, 'HH24:MI'), 'YYYY-MM-DD HH24:MI') as full_date,
to_char(trunc(to_date(col_1, 'HH24:MI'), 'HH24'), 'YYYY-MM-DD HH24:MI') as truncated
from t;
C FULL_DATE TRUNCATED
- ---------------- ----------------
A 2016-09-01 09:56 2016-09-01 09:00
B 2016-09-01 10:03 2016-09-01 10:00
C 2016-09-01 21:53 2016-09-01 21:00
That gives you the lower bound of your range. You can add an hour to the calculated date to get the upper limit, and then convert both back to string, and concatenate them together:
with t (col_2, col_1) as (
select 'A', '9:56' from dual
union all select 'B', '10:03' from dual
union all select 'C', '21:53' from dual
)
select col_2,
to_char(trunc(to_date(col_1, 'HH24:MI'), 'HH24'), 'HH24:MI') ||' - '||
to_char(trunc(to_date(col_1, 'HH24:MI') + 1/24, 'HH24'), 'HH24:MI')
from t;
C TO_CHAR(TRUNC
- -------------
A 09:00 - 10:00
B 10:00 - 11:00
C 21:00 - 22:00
You could also try to extract the hour value from your string and manipulate that, but then you have to manually deal with times between 23:00 and 00:00.
A third option is to use an interval instead of a date:
to_char(extract(hour from to_dsinterval('0 ' || col_1 || ':00')), 'FM00') ||':00 - '||
to_char(extract(hour from to_dsinterval('0 ' || col_1 || ':00')) + 1, 'FM00') ||':00'
but again this would show a time of say 23:15 as 23:00 - 24:00, so you'd need extra handling to show the upper bound as 00:00 in that case.

Count the no of saturdays and sundays in date range - oracle [duplicate]

This question already has answers here:
Number of fridays between two dates
(7 answers)
Closed 8 years ago.
I have two parameters(start_Date,end_Date) from table1
I'm trying to count no of saturdays and sundays in a date range
star_Date=8/20/2014 13:52
end_Date=8/28/2014 13:52
And result should be like this
Start_Date end_date No_of_leaves
8/20/2014 13:52 8/28/2014 13:52 2
Update Section
SELECT retouch_req_time,retouch_submit_time,(
SELECT Count(*) FROM (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday') dt
FROM (WITH t AS (SELECT To_date (retouch_req_time, 'MM/DD/YYYY HH24:MI') start_date, To_date (retouch_submit_time, 'MM/DD/YYYY HH24:MI') end_date FROM TT))
CONNECT BY LEVEL <= end_date - start_date + 1) WHERE dt IN ('friday','saturday')) as worked_hours
FROM TT
You can try using hierarchical queries
WITH t
AS (SELECT To_date ('8/20/2014 13:52', 'MM/DD/YYYY HH24:MI') start_date,
To_date ('8/28/2014 13:52', 'MM/DD/YYYY HH24:MI') end_date
FROM dual)
SELECT Count(*)
FROM (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday') dt
FROM t
CONNECT BY LEVEL <= end_date - start_date + 1)
WHERE dt IN ( 'friday', 'saturday' );
RESULT
------
2
* The dates are listed by expanding the range.
* The TO_CHAR function is used to obtain the weekday
* Count everthing which is a friday or saturday
If you want to find the day wise count, then you can try
SELECT To_char(dat, 'DY'),
Count(*)
FROM (SELECT To_date ('8/20/2014 13:52', 'MM/DD/YYYY HH24:MI')
+ num dat
FROM (SELECT LEVEL - 1 num
FROM dual
CONNECT BY LEVEL <= Abs(To_date ('8/20/2014 13:52',
'MM/DD/YYYY HH24:MI') -
To_date (
'8/28/2014 13:52'
,
'MM/DD/YYYY HH24:MI')) - 1
))
WHERE To_char(dat, 'DY') IN ( 'FRI', 'SAT' )
GROUP BY To_char(dat, 'DY');
RESULTS
TO_CHAR(DAT,'DY') COUNT(*)
----------------- --------
FRI 1
SAT 1
You can calculate the number of saturdays and sundays like this:
with t(d) as (
select sysdate + level from dual connect by rownum < 10
)
select count(case when trim(to_char(d, 'DAY')) in ('SATURDAY', 'SUNDAY') then 1 end) cnt from t
CNT
---
2
If you don't have a range of dates then:
with t(a, b) as (
select sysdate a, sysdate + 10 b from dual connect by rownum < 10
), t2(d) as (
select a + level - 1 from t connect by rownum <= b - a
)
select count(case when trim(to_char(d, 'DAY')) in ('SATURDAY', 'SUNDAY') then 1 end) cnt from t2
CNT
---
2

PL/SQL: TO_CHAR show format

So I have this code here:
create or replace FUNCTION calc_length(
START_TIME IN number,
FINISH_TIME IN number
) RETURN NUMBER IS
BEGIN
RETURN ( (FINISH_TIME - START_TIME ) ;
END
And I want to show the result in the format as H:mm
I tried TO_CHAR function but it accepts a strict preset formats.
Few examples - copy, paste to see the oputput:
SELECT trunc(mydate / 3600) hr
, trunc(mod(mydate, 3600) / 60) mnt
, trunc(mod(mydate, 3600) / 60 /60) sec
FROM
(
SELECT (to_date('01/02/2013 23:00:00', 'mm/dd/yyyy hh24:mi:ss') -
to_date('01/01/2013 07:00:00', 'mm/dd/yyyy hh24:mi:ss')) * 86400 mydate
FROM dual
)
/
Select hh, mi, ss From
(
Select EXTRACT(hour From Cast(SYSDATE as timestamp)) hh,
EXTRACT(minute From Cast(SYSDATE as timestamp)) mi,
EXTRACT(second From Cast(SYSDATE as timestamp)) ss
From dual
)
/
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('21/02/2012 06:10:53 am', 'dd/mm/yyyy hh:mi:ss am') AS TIMESTAMP) end_date
, CAST(to_date('21/02/2012 12:05:00 am', 'dd/mm/yyyy hh:mi:ss am') AS TIMESTAMP) start_date
From dual
))
/

Resources