Show UTC in timestamp Oracle SQL - sql

In Oracle SQL, this:
SELECT to_timestamp('2021-08-11 16:25:54', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
Returns:
11-AUG-21 04.25.54.000000000 PM
However, my input timestamp also contains UTC: 2021-08-11 16:25:54 UTC
Desired result:
11-AUG-21 04.25.54.000000000 PM UTC
The docs specify to include Z... However this does not work:
--Invalid date format
SELECT to_timestamp('2021-08-11 16:25:54 UTC', 'YYYY-MM-DD HH24:MI:SS Z') FROM DUAL;

First of all, you need to_timestamp_tz() instead of to_timestamp, and secondly you need to specify correct format: TZR instead of Z:
-- TZR = time zone region
SELECT to_timestamp_tz('2021-08-11 16:25:54 UTC', 'YYYY-MM-DD HH24:MI:SS TZR') FROM DUAL;

You can use at time zone
SELECT to_timestamp('2021-08-11 16:25:54', 'YYYY-MM-DD HH24:MI:SS') at time zone 'UTC' dt
FROM DUAL;
EDIT
Correct version, thanks to #WernfriedDomscheit
SELECT FROM_TZ(to_timestamp('2021-08-11 16:25:54', 'YYYY-MM-DD HH24:MI:SS'), 'UTC') ts
FROM DUAL;

Related

Convert epoch time to timestamp in oracle database with system timezone

Can someone please suggest me how to convert epoch time to timestamp in oracle including the database timezone. I am currently using below code:
cast ( TO_TIMESTAMP_TZ('1970-01-01 00:00:00.0 UTC', 'YYYY-MM-DD HH24:MI:SS.FF TZR') + NUMTODSINTERVAL(value/1000, 'SECOND') as timestamp with local time zone)
But it appears this is converting to the sessiontimezone. I need it to be converted to dbtimezone
(In my case select dbtimezone gives PST time and select sessiontimezone gives Asia/Calcutta time.)
Data type timestamp with local time zone always shows date/time at SESSIONTIMEZONE
Try
(TO_TIMESTAMP_TZ('1970-01-01 00:00:00.0 UTC', 'YYYY-MM-DD HH24:MI:SS.FF TZR') + NUMTODSINTERVAL(value/1000, 'SECOND')) AT TIME ZONE DBTIMEZONE
Or with literals:
(Timestamp '1970-01-01 00:00:00 UTC' + value/1000 * INTERVAL '1' SECOND) AT TIME ZONE DBTIMEZONE

Oracle - to_date() parse of 00:00:00

I am trying to format into Date from Date string by following the way,
select to_date('11/19/2019 00:00:00', 'MM/DD/YYYY HH24:MI:SS') as currentdate from dual;
The output should be,
11/19/2019 12:00:00 AM
But, I am getting the output as,
11/19/2019
When I execute following,
select to_date('11/19/2019 00:00:01', 'MM/DD/YYYY HH24:MI:SS') as currentdate from dual;
The correct output I am getting,
11/19/2019 12:00:01 AM
My nls_date_format is DD-MON-RR.
My nls_time_format is HH.MI.SSXFF AM.
I want output in the mentioned format. For all other values except than 00:00:00 is working fine.
Why 00:00:00 is not converting into the required format? Is there any way to achieve this?
You are getting the correct output. Only it is displayed in the default date format of your session (or database), which seems to be mm/dd/yyyy.
You control the default date format of your session with paramter nls_date_format:
alter session set nls_date_format = 'MM/DD/YYYY HH24:MI:SS';
select to_date('11/19/2019 00:00:00', 'MM/DD/YYYY HH24:MI:SS') as currentdate from dual;
Alternatively, you can use to_char() to format your date to a specific format:
select to_char(
to_date('11/19/2019 00:00:00', 'MM/DD/YYYY HH24:MI:SS'),
'MM/DD/YYYY HH24:MI:SS'
) as currentdate from dual;
If you want the AM format you will need this:
select to_char(to_date('19/11/2019 12:00:00 AM','dd/mm/yyyy hh:mi:ss AM'),'dd/mm/yyyy hh:mi:ss AM')
from dual;
If you run it like this:
select to_char(to_date('19/11/2019 00:00:00','dd/mm/yyyy hh:mi:ss AM'),'dd/mm/yyyy hh:mi:ss AM')
from dual;
You will get an error.
When your date format is not 24 hours(hh24) then your value for hour needs to be between 1 and 12.
Here is the DEMO
After some research I have realised what OP wants(from his comments and after he entered some more details).
Solution for OP is:
Step 1:
ALTER session SET NLS_DATE_FORMAT = 'DD-MON-RR HH.MI.SS AM';
Step 2 now this will work:
select to_date('11/19/2019 00:00:00', 'MM/DD/YYYY HH24:MI:SS') as currentdate from dual;

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';

Oracle SQL: convert UTC to CST

I would like to convert UTC date/time to local CST.
The below function works however it gives 6 hours difference when there should only be 5 hours (until day light saving on 11/2/2014).
CAST((FROM_TZ(CAST(utc_date AS TIMESTAMP),'UTC') AT TIME ZONE 'CST') AS DATE) cst_date
also tried a variation
to_date(to_char((from_tz(to_timestamp(to_char(utc_date, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') ,'UTC')
at time zone 'CST'),'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD HH24:MI:SS') as cst_date,
Using the "US/Central" as the target timezone seems to produce the right result.
select from_tz(CAST ('15-oct-2014' AS TIMESTAMP),'GMT') at TIME ZONE 'US/Central' with_daylight_savings,
from_tz(CAST ('15-nov-2014' AS TIMESTAMP),'GMT') at TIME ZONE 'US/Central' without_daylight_savings
from dual;
WITH_DAYLIGHT_SAVINGS WITHOUT_DAYLIGHT_SAVINGS
--------------------------------------------------------------------------------------
14-OCT-14 07.00.00.000000000 PM US/CENTRAL 14-NOV-14 06.00.00.000000000 PM US/CENTRAL
Use timezone region instead of timezone abbr ('CST'). You may find the desired timezone here:
SELECT * from v$timezone_names where tzabbrev = 'CST';
Maybe you need 'CST6CDT' instead of 'CST'
Maybe a stupid approach, but what do you get from this query?
SELECT
TO_CHAR((TIMESTAMP '2014-01-01 00:00:00' + LEVEL * INTERVAL '1' DAY) AT TIME ZONE 'America/Chicago', 'yyyy-mm-dd hh24:mi TZH:TZM') AS dst,
TO_CHAR((FROM_TZ(CAST(DATE '2014-01-01' AS TIMESTAMP), 'UTC') + LEVEL * INTERVAL '1' DAY) AT TIME ZONE 'America/Chicago', 'yyyy-mm-dd hh24:mi TZH:TZM') AS dst
FROM dual
CONNECT BY LEVEL <= 365;
Is it as expected?

Need help: Timezone related Oracle SQL QUERY

I need your help in understanding the below query.
SELECT To_date(To_char(( ( To_timestamp_tz(From_tz(Cast(l_end_date AS TIMESTAMP)
,
dbtimezone))
) AT
TIME
ZONE ( l_time_zone ) ),
'YYYY-MM-DD HH24:MI:SS'
), 'YYYY-MM-DD HH24:MI:SS')
FROM dual
where l_end_date = 31-Dec-2018
Well, ultimately it converts the date 31-Dec-2018 at midnight into whatever local timezone date you indicate with l_time_zone. E.g., for me with dbtimezone = +00:00 and l_time_zone set to Australia/Sydney I get 31/12/2018 11:00:00 AM.
But to fully understand you may just want to look at each function's documentation:
DBTIMEZONE
TO_TIMESTAMP_TZ
FROMTZ
TO_DATE
TO_CHAR
AT TIME ZONE