How to show interval between two timestamps in hh24:mi notation? [duplicate] - sql

This question already has answers here:
Oracle SQL Hours Difference between dates in HH:MM:SS
(5 answers)
Closed 4 years ago.
How can I show interval between 2 timestamps in 'hh24:mi' format?
I have a Table with two Datestamps StartTime and EndTime between which I would like to see the difference in Hours and Minutes as HH24:mi
The difference is never above 24 hours but StartTime can be on day 1 and EndTime can be on day .
Example :
StartTime = 19/02/2019 22:52:42
EndTime = 20/02/2019 02:56:42
Result wanted = 04:04
So far the best results I managed to have are :
4,8 : ROUND ((EndTime - StartTime) * 24,2) INTERVAL
4:4 : EXTRACT (hour from numtodsinterval (EndTime - add_months (StartTime, floor (months_between (EndTime,StartTime))), 'day')) || ':'
|| EXTRACT (minute from numtodsinterval (EndTime - add_months (StartTime, floor (months_between (EndTime, StartTime))), 'day'))
Hours & Minutes in a seperate field : Hrs : 4 | Min : 4
trunc(((86400*(EndTime-StartTime))/60)/60)-24*(trunc((((86400*(EndTime-StartTime))/60)/60)/24)) "Hrs"
trunc((86400*(EndTime-StartTime))/60)-60*(trunc(((86400*(EndTime-StartTime))/60)/60)) "Min"

I wrote an anonymous block using your values. but if you are querying from a table it is not required. you can apply this logic in select query itself to get output.
declare
start_time date;
end_time date;
output number;
f_out varchar2(10);
begin
start_time :=to_Date('19/02/2019 22:52:42','dd/mm/yyyy hh24:mi:ss');
end_time:= to_Date('20/02/2019 02:56:42','dd/mm/yyyy hh24:mi:ss');
select (end_time-start_time) into output from dual;
--output := trunc(output*86400/3600);
f_out:=lpad(trunc(output*86400/3600),2,'0')||':'||lpad(mod(output*86400,3600)/60,2,'0');
dbms_output.put_line(f_out);
end;

You can do this by processing dates:
select to_char(date '2000-01-01' + (end_time - start_time), 'hh24:mi')
from (select to_Date('2019-02-19 22:52:42', 'yyyy-mm-dd hh24:mi:ss') as start_time,
to_Date('2019-02-19 02:56:42', 'yyyy-mm-dd hh24:mi:ss') as end_time
from dual
) t
Here is a db<>fiddle.

Related

How to subtract 2 timestamp (one as a date, other in HH24:MI format) and get the result in HH24:MI format in OracleSQL

I have a table with two columns, Start_time and SLA.
Start time updates for each day and is in a date format e.g., 01-Jun-2021 19:15:38
SLA column is having fixed HH24MI as 2010
I want 1915 - 2010 to be -00:55 (as in HH24MI format)
SELECT TO_CHAR((TO_CHAR(START_TIME,'HH24')||TO_CHAR(START_TIME,'MI'))-2010,'0000')
FROM DUAL;
Above will give the result as -0095 but I want it to be -00:55
Store the start_time as a DATE data type and the sla as an INTERVAL DAY TO SECOND data type:
CREATE TABLE table_name (
start_time DATE,
sla INTERVAL DAY TO SECOND
);
Then your data would be:
INSERT INTO table_name ( start_time, sla ) VALUES (
TO_DATE('01-Jun-2021 19:15:38', 'DD-MON-YYYY HH24:MI:SS', 'NLS_DATE_LANGUAGE=American'),
INTERVAL '20:10:00' HOUR TO SECOND
);
And, to find the difference, you can use:
SELECT start_time,
sla,
(start_time - TRUNC(start_time)) DAY TO SECOND - sla AS difference
FROM table_name
Which outputs:
START_TIME
SLA
DIFFERENCE
2021-06-01 19:15:38
+00 20:10:00.000000
-000000000 00:54:22.000000000
If you want the output as a formatted string, rather than as an interval, then:
SELECT start_time,
sla,
CASE WHEN difference < INTERVAL '0' HOUR THEN '-' END
|| TO_CHAR( ABS( EXTRACT( HOUR FROM difference ) ), 'FM00' )
|| TO_CHAR( ABS( EXTRACT( MINUTE FROM difference ) ), 'FM00' )
AS difference
FROM (
SELECT start_time,
sla,
(start_time - TRUNC(start_time)) DAY TO SECOND - sla AS difference
FROM table_name
)
Which outputs:
START_TIME
SLA
DIFFERENCE
2021-06-01 19:15:38
+00 20:10:00.000000
-0054
db<>fiddle here

Oracle - fetch first 3 days record of the current month

I need to fetch first 3 days record of the current month from Oracle database. Something like below,
Select * from test.purchase where create_ts=( first 3 days of the current month)
Select *
from test.purchase
where create_ts between trunc(sysdate,'mm') and trunc(sysdate,'mm') + 3
You can get the first day of the current month with the trunc(date) function, using the MM date format element.
select to_char(trunc(sysdate, 'MM'), 'YYYY-MM-DD Hh24:MI:SS') from dual;
TO_CHAR(TRUNC(SYSDA
-------------------
2017-06-01 00:00:00
You can then use date arithmetic to either add a number of days or an interval representing that number to get the fourth day of the month:
select to_char(trunc(sysdate, 'MM') + 3, 'YYYY-MM-DD Hh24:MI:SS') from dual;
TO_CHAR(TRUNC(SYSDA
-------------------
2017-06-04 00:00:00
If you want data up to the start of that fourth day, i.e. up to 23:59:59 on the 3rd, you can look for values less than midnight on the 4th:
select * from test.purchase
where create_ts >= trunc(sysdate, 'MM')
and create_ts < trunc(sysdate, 'MM') + 3;
You could potentially use between, but as that is inclusive you would need to specify the absolute latest time on the 3rd - checking whether the column is a date or a timestamp, which might change, and can be a little confusing. If you used between trunc(sysdate, 'MM') and trunc(sysdate, 'MM') + 3 then you would include any records at exactly midnight on the 4th, which isn't what you want. I find using >= and < clearer and less ambiguous, even if it is a little more typing.
If the column is actually a timestamp then you can cast the calculated dates to timestamp too, and/or an use interval for the upper bound:
select * from test.purchase
where create_ts >= cast(trunc(sysdate, 'MM') as timestamp)
and create_ts < cast(trunc(sysdate, 'MM') + 3 as timestamp);
... or:
...
and create_ts < cast(trunc(sysdate, 'MM') as timestamp) + interval '3' day;

SQL extract hour from timestamp

This query: select EXTRACT(HOUR FROM 1435047532) as hour from TABLENAME;
Returns this error: "invalid extract field for extract source".
I'm trying to extract the hour from a given timestamp. Maybe the problem is the format of timestamp field is NUMBER and not TIMESTAMP?
You can convert your numeric seconds-since-epoch time to a TIMESTAMP type using:
TIMESTAMP '1970-01-01 00:00:00' + NUMTODSINTERVAL( your_time_since_epoch, 'SECOND' )
So to get the hours:
SELECT EXTRACT( HOUR FROM TIMESTAMP '1970-01-01 00:00:00'
+ NUMTODSINTERVAL( 1435047532, 'SECOND' ) )
FROM DUAL;
If you need to handle leap seconds then you will need to create a function/package to handle this.
try this
select extract(hour from (select to_date('19700101', 'YYYYMMDD')
+ ( 1 / 24 / 60 / 60 ) * 1435047532 from dual)) from dual

Condition for current time greater than or equal to from time and current time less than or equal to time in ORACLE

Condition not working because using TO_CHAR(),but how to extract time? following is my query:
SELECT *
FROM SUPPLY_TIMING
WHERE TO_CHAR (SYSDATE, 'HH:Mi') >= TO_CHAR (FROM_TIME, 'HH:Mi')
AND TO_CHAR (SYSDATE, 'HH:Mi') <= TO_CHAR (TO_TIME, 'HH:Mi')
It looks like you are interested only in the time but not in the date part. Assuming data type of FROM_TIME and TO_TIME are DATE or TIMESTAMP you can do this:
select *
FROM SUPPLY_TIMING
WHERE EXTRACT(HOUR FROM SYSDATE) + EXTRACT(MINUTE FROM SYSDATE)/60
BETWEEN EXTRACT(HOUR FROM FROM_TIME) + EXTRACT(MINUTE FROM FROM_TIME)/60
AND EXTRACT(HOUR FROM TO_TIME) + EXTRACT(MINUTE FROM TO_TIME)/60
At first glance, my guess is that your format mask is what's causing the problem. The HH component will give you the hours in twelve hour format, so 1pm will be returned as 01, I think if you used HH24 instead, you would get 13, making the string comparison work as intended:
SELECT *
FROM SUPPLY_TIMING
WHERE TO_CHAR (SYSDATE, 'HH24:Mi') >= TO_CHAR (FROM_TIME, 'HH24:Mi')
AND TO_CHAR (SYSDATE, 'HH24:Mi') <= TO_CHAR (TO_TIME, 'HH24:Mi')

Oracle Add 1 hour in SQL

I am just trying to add 1 hour to a value, it is kind of complicated on where and why i am doing this but basically i just need to query something like this
select DATE_ADD(hh,1,'2014-10-15 03:30:00 pm') from dual
I keep reading old articles that say to use dateAdd or date_add but I keep getting invalid identifier errors.
select sysdate + 1/24 from dual;
sysdate is a function without arguments which returns DATE type
+ 1/24 adds 1 hour to a date
select to_char(to_date('2014-10-15 03:30:00 pm', 'YYYY-MM-DD HH:MI:SS pm') + 1/24, 'YYYY-MM-DD HH:MI:SS pm') from dual;
Use an interval:
select some_date_column + interval '1' hour
from your_table;
You can use INTERVAL type or just add calculated number value - "1" is equal "1 day".
first way:
select date_column + INTERVAL '0 01:00:00' DAY TO SECOND from dual;
second way:
select date_column + 1/24 from dual;
First way is more convenient when you need to add a complicated value - for example, "1 day 3 hours 25 minutes 49 seconds".
See also: http://www.oracle-base.com/articles/misc/oracle-dates-timestamps-and-intervals.php
Also you have to remember that oracle have two interval types - DAY TO SECOND and YEAR TO MONTH.
As for me, one interval type would be better, but I hope people in oracle knows, what they do ;)
Old way:
SELECT DATE_COLUMN + 1 is adding a day
SELECT DATE_COLUMN + N /24 to add hour(s) - N being number of hours
SELECT DATE_COLUMN + N /1440 to add minute(s) - N being number of minutes
SELECT DATE_COLUMN + N /86400 to add second(s) - N being number of seconds
Using INTERVAL:
SELECT DATE_COLUMN + INTERVAL 'N' HOUR or MINUTE or SECOND - N being a number of hours or minutes or seconds.
To add/subtract from a DATE, you have 2 options :
Method #1 :
The easiest way is to use + and - to add/subtract days, hours, minutes, seconds, etc.. from a DATE, and ADD_MONTHS() function to add/subtract months and years from a DATE. Why ? That's because from days, you can get hours and any smaller unit (1 hour = 1/24 days), (1 minute = 1/1440 days), etc... But you cannot get months and years, as that depends on the month and year themselves, hence ADD_MONTHS() and no add_years(), because from months, you can get years (1 year = 12 months).
Let's try them :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 20:42:02
SELECT TO_CHAR((SYSDATE + 1/24), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 21:42:02
SELECT TO_CHAR((SYSDATE + 1/1440), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 20:43:02
SELECT TO_CHAR((SYSDATE + 1/86400), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 20:42:03
-- Same goes for subtraction.
SELECT SYSDATE FROM dual; -- prints current date: 19-OCT-19
SELECT ADD_MONTHS(SYSDATE, 1) FROM dual; -- prints date + 1 month: 19-NOV-19
SELECT ADD_MONTHS(SYSDATE, 12) FROM dual; -- prints date + 1 year: 19-OCT-20
SELECT ADD_MONTHS(SYSDATE, -3) FROM dual; -- prints date - 3 months: 19-JUL-19
Method #2 : Using INTERVALs, you can or subtract an interval (duration) from a date easily. More than that, you can combine to add or subtract multiple units at once (e.g 5 hours and 6 minutes, etc..)
Examples :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 21:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' MINUTE), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 21:35:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 21:34:16
SELECT TO_CHAR((SYSDATE + INTERVAL '01:05:00' HOUR TO SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour and 5 minutes: 19-OCT-2019 22:39:15
SELECT TO_CHAR((SYSDATE + INTERVAL '3 01' DAY TO HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 3 days and 1 hour: 22-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE - INTERVAL '10-3' YEAR TO MONTH), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date - 10 years and 3 months: 19-JUL-2009 21:34:15
The calculation is simple
if you want to add 1 hour in the date .
every day have 24 hour , you can add .
select sysdate + 1/24 from dual;
if you want 1 day to add
select sysdate + 24/24 from dual;
or
select sysdate + 1 from dual;
same as for 2, 3 , 4 day
For static date you have the answer below.