Hours and minutes between 2 incorrectly formatted datetimes - sql

So i have some timestamps in a DB and i want to get the hours and minutes difference from them
The problem is the timestamp portion is formatted incorrectly where the hour is always 12 and the minutes portion is actually the hours and the seconds is actually the minutes.
Example DB timestamp: 10/1/2020 12:08:52 AM
So in the above example the time is actually 8:52 AM not 12:08 AM
How can i convert this datetime to something i can use in order to calculate the difference in minutes and hours between these 2 oddly formatted timestamps?
My ideal end goal is something that displays the difference in the HH:MM format
EDIT: the timestamps in oracle actually look like below, and in this eaxmple the 12 means nothing and 18 is actually the hours.
Example of what I'm looking for:
01-OCT-20 12.18.44.000000000 AM - 01-OCT-20 12.12.42.000000000 AM
Output: 06:02 . so the timespan would be 6 hours and 2 minutes in this case.
Thanks,

You can turn your string to an Oracle date (resp timestamp) with to_date() (resp to_timestamp()):
to_timestamp(mystring, 'dd/mm/yyyy ss:hh12:mi am')
Then you can use date arithmetics to compute the difference. Substrating timestamps gives you an interval, which is pretty much what you seem to be looking for, so:
to_timestamp(mystring1, 'dd/mm/yyyy ss:hh12:mi am')
- to_timestamp(mystring2, 'dd/mm/yyyy ss:hh12:mi am')
as myinterval

Like so?
(my default date format is 'yyyy-mm-dd hh24:mi:ss' in Oracle ...)
WITH
indata(sdb) AS (
SELECT '10/1/2020 12:08:52 AM' FROM dual
UNION ALL SELECT '10/1/2020 12:08:52 PM' FROM dual
)
SELECT
TO_TIMESTAMP(sdb,'dd/mm/yyyy 12:hh:mi AM') AS ts
FROM indata;
-- out ts
-- out ---------------------
-- out 2020-01-10 08:52:00
-- out 2020-01-10 20:52:00

Related

choose from a time period oracle sql

I have timestamp date format in column FIRST_DATE and i need to choose time period from a certain hour, for ex. all from 18:00 10.05.21 to 18:00 11.05.2021
the problem is that date column in timestamp format - FIRST_DATE:
10/05/2020 0:00:03,000000 TIMESTAMP(6)
so i tried to use it:
select
count(*)
from TABLE
where to_char(FIRST_DATE, 'HH24:MI')>='18:00'
so with this way i was able to limit the start period by time, but if i add date to this my conditions stop working
and to_char(FIRST_DATE, 'DD-MON-YY')>='10-MAY-21'
how can i correct my script to select all from 18:00 10.05.21 to 18:00 11.05.2021
Don't compare dates (or timestamps) with strings. '18:00' and '10-MAY-21' are strings. Use TO_TIMESTAMP with appropriate format mask, e.g. (lines #5 and 6):
SQL> with test (first_date) as
2 (select to_timestamp('10/05/2020 23:00:03,000000', 'dd/mm/yyyy hh24:mi:ss,ff3') from dual)
3 select *
4 from test
5 where first_date between to_timestamp('10/05/2020 18:00:00,000000', 'dd/mm/yyyy hh24:mi:ss,ff3')
6 and to_timestamp('11/05/2020 18:00:00,000000', 'dd/mm/yyyy hh24:mi:ss,ff3')
7 /
FIRST_DATE
---------------------------------------------------------------------------
10.05.20 23:00:03,000000000
SQL>

Convert date oracle's timestamp to ISO-8601 date datatype [duplicate]

This question already has answers here:
Timezone date format in Oracle
(2 answers)
Closed 1 year ago.
I am looking for a query in Oracle 12c to convert a 18-12-2003 13:15:00 to 2003-12-18T13:15:00+01:00 in European time zone as datetime datatype.
Is that possible or am I missing something?
First you need to convert the string (I assume your input data is a string, rather than proper DATE or TIMESTAMP value), then you can attach the time zone.
There are several time zones in Europe, you must be more specific.
FROM_TZ(TO_TIMESTAMP('18-12-2003 13:15:00', 'DD-MM-YYYY HH24:MI:SS'), 'Europe/...')
Once you did that, you can output the result in arbitrary format:
TO_CHAR(
FROM_TZ(TO_TIMESTAMP('18-12-2003 13:15:00', 'DD-MM-YYYY HH24:MI:SS'), 'Europe/...'),
'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM'
)
If you want to convert all dates in the column to that format for the time zone CET and you are sure that the offset always is 1, then you could do this:
SELECT TO_CHAR(FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '1:00'),'YYYY"-"MM"-"DD"T"HH24":"MI":"SSTZR')
FROM DUAL;
However, the question is what to do with daylight savings time. Is the offset going to change when DST goes into effect ? There are a lot of considerations there - this question (credits to #Wernfried Domscheit) has a nice overview.
For example if you data is in UTC time zone and you want to display it in CET, then you could convert it like this:
Note there is 2 hours offset in summer and 1 in winter.
WITH dates (season,dt) AS
(
SELECT 'summer', TO_DATE('01-AUG-2021','DD-MON-YYYY') FROM DUAL UNION ALL
SELECT 'winter', TO_DATE('01-JAN-2021','DD-MON-YYYY') FROM DUAL
)
SELECT dt,
season,
TO_CHAR(
FROM_TZ( CAST( dt AS TIMESTAMP ), 'UTC' )
AT TIME ZONE 'CET',
'YYYY-MM-DD HH24:MI:SS TZH:TZM TZR'
) AS cet_timezone
FROM dates;
01-AUG-2021 summer 2021-08-01 02:00:00 +02:00 CET
01-JAN-2021 winter 2021-01-01 01:00:00 +01:00 CET

ORACLE using TO_DATE to check if item is within last hour

I have a query that I am trying to use TO_DATE to check if ERROR_DT is a data that is within one hour of the current time
Here is what I have so far
SELECT BERROR_DT FROM SomeTable
WHERE ERROR_DT>=TO_CHAR(TO_DATE( SYSDATE, 'MM/DD/YYYY HH12:MI:SS AM') -1, 'fmMM/DDfm/YYYY HH12:MI:SS AM');
Error_DT has a value of (e.g.) 5/18/2020 6:45:15 PM
When I run this I get
ORA-01830: date format picture ends before converting entire input string
I followed the said link and it still is not working. How would I fix this so that I can still remove all 0s in front of the month and the date?
I would suggest converting the date string to the corresponding date value, then do the comparison:
select berror_dt
from sometable
where to_date(error_dt, 'fmMM/DD/YYYY HH12:MI:SS AM') >= sysdate - interval '1' hour
Bottom line, you should fix your data model and store dates as a date-like datatype rather than as a string. The above predicate is not efficient, because the conversion needs to be executed for each and every value of error_dt before the filtering applies, hence defeating an existing index on the column.
Obviously wrong thing you're doing is applying TO_DATE to SYSDATE which is a function that returns DATE datatype.
What you could do is to subtract sysdate and error_dt (I presume its datatype is DATE as well) and see whether difference is less than 1 hour. As difference of two dates is number of days, you have to divide it by 24 (as there are 24 hours in a day).
Something like this:
SQL> alter session set nls_date_format = ' dd.mm.yyyy hh:mi:ss am';
Session altered.
SQL> with test (id, error_dt) as
2 (select 1, to_date('18.05.2020 10:30:15 PM', 'dd.mm.yyyy hh:mi:ss am') from dual
3 union all
4 select 2, to_date('18.05.2020 05:20:55 AM', 'dd.mm.yyyy hh:mi:ss am') from dual)
5 select t.id, t.error_dt, sysdate
6 from test t
7 where sysdate - t.error_dt < 1 / 24;
ID ERROR_DT SYSDATE
---------- ----------------------- -----------------------
1 18.05.2020 10:30:15 PM 18.05.2020 11:02:24 PM
SQL>
If ERROR_DT is a DATE value you just need to use something like
SELECT BERROR_DT
FROM SomeTable
WHERE ERROR_DT >= SYSDATE - INTERVAL '1' HOUR
or if you prefer to use old-fashioned pre-INTERVAL calculations
SELECT BERROR_DT
FROM SomeTable
WHERE ERROR_DT >= SYSDATE - (1/24)

How to calculate hours from varchar2 fields?

I have two varchar2 date fields like clock_in and clock_out. I am inserting datetime by sysdate so the date looks like this:
Clock_In Clock_Out
12-28-13 08:00 AM 12-28-13 05:00 PM
Now I want to calculate the no of hours he work. Can you please help in this matter?
You could just convert the data to dates using the to_date function, and then subtract the two values. Since subtracting dates returns a difference in days, you can simply multiply by 24 to get the difference in hours:
SELECT (TO_DATE(clock_out, 'DD-MM-YY HH:MI AM') -
TO_DATE(clock_in, 'DD-MM-YY HH:MI AM')) * 24 AS hours_worked
FROM my_table
EDIT:
An even better solution would probably be to save clock_in and clock_out as date fields to begin with and avoid the hassle of converting in the query, but I'm not sure this is possible for the OP.

Oracle - Using to_date, how to convert varchar to today's date

I have a table where I store the times as varchars:
Times
starttime
00:00
16:00
22:00
From this table I can convert the column to a date like this:
Select to_date(starttime,'hh24:mi') from times
This gives me the following:
01/03/2013 00:00:00
01/03/2013 16:00:00
01/03/2013 22:00:00
How can I change this query so I can prefix the time values with today's date so I get the following instead: (16/03/2013 is today's date)
16/03/2013 00:00:00
16/03/2013 16:00:00
16/03/2013 22:00:00
Thanks
to_date(to_char(sysdate, 'dd.mm.yyyy')||' '||starttime, 'dd.mm.yyyy hh24:mi')
You can add the difference between the current date and the start of the month. I prefer this to string operations as you stick with dates, but it doesn't make much difference.
You can use TRUNC() to work it out:
select to_date('09:00','hh24:mi') + ( trunc(sysdate) - trunc(sysdate, 'mm'))
from dual
SQL Fiddle
trunc(sysdate) is the earliest today and trunc(sysdate, 'mm') is the beginning of the month. Oracle's date arithmetic means that it returns a day difference between today and the beginning of the month; giving you the difference you need to add to your original TO_DATE().