CAST(CURRENT_TIMESTAMP AS TIME) - sql

i am trying to work with timestamps and manipulate the data out of them so i can measure different things in our database.
currently i have a column that holds a "DATE" but in fact contains a whole stamp 'DD/MM/YYYY HH24:MI:SS'
i want to be able to grab all entries where "DTIME" between "09:00" and "09:15" however have not been able to cast it correctly.
If i was to output the column without any conversion it would look like this
SELECT ia.DTIME3
FROM ISIS_AUDIT ia
WHERE ia.DTIME3 like to_date('24/01/2019', 'DD/MM/YYYY');
OUTPUT: 24/JAN/19
if i was to convert it to_char,
SELECT to_char(ia.DTIME3, 'DD/MM/YYYY HH24:MI:SS')
FROM ISIS_AUDIT ia
WHERE ia.DTIME3 like to_date('24/01/2019', 'DD/MM/YYYY');
OUTPUT: 24/01/2019 07:10:52
I want to be able to take this DTIME3 and find entries between the times but CAST and CONVERT to TIME doesnt work.
This is my working option but it outputs the date still and i dont want to have to specify the date so it can be run across any day of the week.
WHERE ia.DTIME3 between to_date('24/01/2019 09:00:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('24/01/2019 09:15:00', 'DD/MM/YYYY HH24:MI:SS');
OUTPUT: 24/01/2019 09:00:01

currently i have a column that holds a "DATE" but in fact contains a whole stamp 'DD/MM/YYYY HH24:MI:SS'
That's what Oracle DATE datatype does : storing a date and time (without fractional seconds, that belong to the TIMESTAMP datatypes). There is no specific format in Oracle for date only (without time).
To filter on the time of the day, you can use the TO_CHAR() function to convert your date to a string that represents its time, and that you can compare :
TO_CHAR(ia.DTIME3, 'hh24:mi') BETWEEN '09:00' AND '09:14'
You can also CAST the date to a timestamp and use the EXTRACT() function :
EXTRACT(HOUR FROM CAST(ia.DTIME3 AS TIMESTAMP)) = 9
AND EXTRACT(MINUTE FROM CAST(ia.DTIME3 AS TIMESTAMP)) < 15

Oracle has DATE and TIMESTAMP data types; both have year, month, day, hour, minute, second components (TIMESTAMP also has fractional seconds). Oracle does not have a TIME data type.
Instead, use TRUNC() to truncate the time component to midnight and add an interval literal:
SELECT *
FROM ISIS_AUDIT
WHERE DTIME BETWEEN TRUNC( DTIME ) + INTERVAL '09:00' HOUR TO MINUTE
AND TRUNC( DTIME ) + INTERVAL '09:15' HOUR TO MINUTE;

and ia.DTIME1 not between to_date('&&S_DATE 08:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 09:20:00', 'DD/MM/YYYY HH24:MI:SS')
and ia.DTIME1 not between to_date('&&S_DATE 11:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 12:40:00', 'DD/MM/YYYY HH24:MI:SS')
and ia.DTIME3 not between to_date('&&S_DATE 08:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 09:20:00', 'DD/MM/YYYY HH24:MI:SS')
and ia.DTIME3 not between to_date('&&S_DATE 11:50:00', 'DD/MM/YYYY HH24:MI:SS') and to_date('&&S_DATE 12:40:00', 'DD/MM/YYYY HH24:MI:SS')
i was trying to do this way however i noticed if i have a start time of 08:30 and a finish time of 09:30 then it falls between 09:00 and 09:15 so i want to exclude it from the table. the current WHERE clause im using is quite specific and will only exclude if the timestamp contains the values specified.
Really it would want to read "DTIME1 to DTIME3 not between 09:00 and 09:15"

Related

PostgreSQL BigInt to DateTime and Add hours to get local time

I am trying to convert the bigint value to date in PostgreSQL
I am using the below code
SELECT TO_CHAR(TO_TIMESTAMP(1564983632051/ 1000),
'YYYY-MM-DD HH24:MI:SS')
then its returning 2019-08-05 07:40:32, which is correct.
However i want to add few hours to it to get local time. Tried with the following query but its throwing an error :
SELECT TO_CHAR(TO_CHAR(TO_TIMESTAMP(1564983632051/ 1000),
'YYYY-MM-DD HH24:MI:SS') + INTERVAL '4 hour')
I do not want to use a separate query, if that's the case i can use
select (to_timestamp('2019-08-05 07:40:32', 'YYYY-MM-DD HH24:MI:SS.US') + interval '4 hour')::timestamp;
this will return the desired output.
I need both conversion and hours addition in a single query.
You should add to TIMESTAMP portion, not to portion casted to CHAR :
SELECT TO_CHAR(
TO_TIMESTAMP(1564983632051/ 1000)+ INTERVAL '4 hour',
'YYYY-MM-DD HH24:MI:SS'
)
The problem is here:
select pg_typeof(TO_CHAR(TO_TIMESTAMP(1564983632051/ 1000), 'YYYY-MM-DD HH24:MI:SS'));
pg_typeof
-----------
text
Adding an interval to a text value is not going to work.
So something like:
select TO_CHAR(TO_TIMESTAMP(1564983632051/1000) + interval '4 hour', 'YYYY-MM-DD HH24:MI:SS') ;
to_char
---------------------
2019-08-05 02:40:32
It is best to stay in a type for operations until the very end. Then apply formatting.

How to add hours to date in 24 hours format

I would like to add, for example, 8 hours to the enddate in a 24 hour format.
I tried adding + 8/24, 'DD-MM-YYYY HH24:MI:SS' on the first line but this gives an error.
This is my query thus far.
SELECT to_char(IN_ENDDATE, 'DD-MM-YYYY HH24:MI:SS')
INTO IN_END_DATE_STRING
FROM DUAL;
Your first line converts a date to a string. You cannot then add 8/24 to it. Do the addition before the conversion:
SELECT to_char(IN_ENDDATE + 8/24.0, 'DD-MM-YYYY HH24:MI:SS')
INTO IN_END_DATE_STRING
FROM DUAL;
IN_ENDDATE really does need to be a date type to allow +8/24 to work. If it's a timestamp, add it as an interval:
IN_ENDDATE + INTERVAL '8' HOUR
This form might be safer to use for a couple of reasons:
it works on both date and timestamps
it's more readable
If IN_ENDDATE is a non-date type (eg varchar) then your query works without the +8/24 because it is being successfully implicitly converted from varchar to date, before being passed to to_char. In this case either be explicit about your conversion:
SELECT to_char(to_date(IN_ENDDATE, 'YYMMDD WHATEVER') + 8/24.0, 'DD-MM-YYYY HH24:MI:SS')
INTO IN_END_DATE_STRING
FROM DUAL
SELECT to_char(to_date(IN_ENDDATE, 'YYMMDD WHATEVER') + INTERVAL '8' HOUR, 'DD-MM-YYYY HH24:MI:SS')
INTO IN_END_DATE_STRING
FROM DUAL
Or set your IN_ENDDATE parameter to really be a date type

Oracle : Date time subtraction

I have to calculate time difference in minutes from current(sysdate) and modified time:-
to_date(to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')
- to_date(to_char(modified, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')
but problem is to_char returns proper time:-
to_char(whenmodified, 'YYYY-MM-DD HH24:MI:SS')
Outputs 2016-05-23 14:55:50
and to_date doesn’t show time:-
to_date(to_char(modified, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')
Outputs: 2016-05-23
Please assist how I can get time difference by converting to_char to to_date.
NOTE:
I cant do sysdate-modified because both sysdate and modified gives date without time e.g 2016-05-23
Using to_char for sysdate or modified give date with time 2016-05-23 14:55:50
As we cant subtracts dates in to_char function I am again converting back them to to_date for getting time.
I am expecting:
2016-05-23 14:55:50 - 2016-05-23 14:53:50 = 2 min
I have to calculate time difference in minutes from current(sysdate) and modified time
Oracle Setup:
CREATE TABLE table_name ( modified DATE );
INSERT INTO table_name
SELECT TIMESTAMP '2016-05-23 14:20:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-05-23 00:00:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-05-01 00:00:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-01-01 00:00:00' FROM DUAL;
Query:
SELECT ( sysdate - modified ) * 24 * 60 AS minute_difference
FROM table_name;
Output:
MINUTE_DIFFERENCE
-----------------
3.66666667
863.666667
32543.6667
206783.667
And to address your comment that:
to_date doesn’t show time
A date always has a time component and never has a format internally to the database (it is represented by 7 or 8 bytes) - the formatting of a date is done by the client program that you use to access the database (and often the default is not to show the time component - however, the time component still exists).
You can change this either in the preferences of your client program or, if they don't use that to control it, by changing the NLS_DATE_FORMAT session parameter:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

Casting String to Date

The below one is working fine and returns date in the desired format
select TO_DATE(TO_CHAR(max(entdate), 'DD/MM/YYYY'), 'DD/MM/YYYY') as last_transaction_date from table;
After adding hh24:mm:ss and error of "format code appears twice" ORA-01810 appears
select TO_DATE(TO_CHAR(max(entdate), 'DD/MM/YYYY hh24:mm:ss'), 'DD/MM/YYYY hh24:mm:ss') as last_transaction_date from table;
I'm not able to understand the difference between both cases
MI not MM for minutes
"Some people mistakenly use the MM format code to represent minutes, thus using the MM format for both the months and the minutes."
select TO_DATE(TO_CHAR(max(entdate), 'DD/MM/YYYY HH24:MI:SS'), 'DD/MM/YYYY HH24:MI:SS') as last_transaction_date from table;

oracle between clause inclusive format HH24:MI

My query looks something like:
select *
from mytable
where date_field between to_date(#from#, 'YYYY/MM/DD HH24:MI')
and to_date(#to#, 'YYYY/MM/DD HH24:MI')
As an example:
if from = 2012/07/18 00:00 and
to = 2012/07/18 00:09
will this include records with timestamp 2012/07/18 00:09:01 to 2012/07/18 00:09:59?
or should I change the statement to:
select *
from mytable
where date_field >= to_date(#from#, 'YYYY/MM/DD HH24:MI')
< to_date(#to#, 'YYYY/MM/DD HH24:MI')
here substituting from : 2012/07/18 00:00 & to: 2012/07/18 00:10 should give me all records with timestamp between midnight & 9M59S past midnight, which is what I want.
The between clause accepts both the interval bounds.
I suggest the second option to you
select *
from mytable
where date_field >= to_date(#from#, 'YYYY/MM/DD HH24:MI')
< to_date(#to#, 'YYYY/MM/DD HH24:MI')
You may find this article interesting.
The date conversion is going to convert the values into dates, which contain all date elements. You have not specified seconds in the strings, so these will become 0.
In other words, the range ":01" - ":59" is not included.
Since you are working with strings and the strings have date elements in the proper order for comparison, why not do string compares instead:
where to_char(datefield, 'YYYY/MM/DD HH24:MI') between #from# and #to#
I think this does exactly what you want, without fiddling around with date arithmetic.
You can also change the statement as you propose, by incrementing the #to# column and using "<" instead of between.
You could do something like this:
SELECT *
FROM mytable
WHERE date_field between to_date(#from#, 'YYYY/MM/DD HH24:MI')
AND to_date(#to#||':59', 'YYYY/MM/DD HH24:MI:SS')
Ignoring the date portion of the DATE elements, since both 00:09:01 and 00:09:59 come after your "to" time of 00:09:00, no, this query will not include those records.
If you want to include those records, you will need to extend your "to" time to 00:10:00 or TRUNC your records's timestamps to the nearest minute.
Edit:
If your from and to are only accurate to the minute, I'd do this:
SELECT *
FROM mytable
WHERE date_field >= to_date(#from#, 'YYYY/MM/DD HH24:MI')
AND date_field < to_date(#to#, 'YYYY/MM/DD HH24:MI') + 1/24/60/60 /* 1 minute */
And make sure you use bind variable for from and to. Is this ColdFusion? If so, use cfqueryparam.