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

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

Related

Casting Local Time to UTC Formating Incorrect

HIRE_DATE is in a 'DATE' column. The timestamp is local (Los Angeles); I would like to convert it to UTC.
I can't for the life of me fathom why the UTC output is mangled (Last 2 digits of YY is the DD; and vice-versa) -- and the time does not convert to UTC.
HIRE_DATE: 30/04/2019 12:00:00 AM
select from_tz(to_timestamp(HIRE_DATE,'DD-MM-YY HH24:MI:SS'), 'America/Los_Angeles') at time zone 'UTC' from TABLE
OUTPUT: 19/04/2030 12:00:00 AM
If HIRE_DATE is a DATE data type then you don't need TO_TIMESTAMP.
TO_TIMESTAMP is used to convert a string (i.e. VARCHAR2) into a TIMESTAMP value but you have a DATE value.
Just do
select from_tz(CAST(HIRE_DATE AS TIMESTAMP), 'America/Los_Angeles') at time zone 'UTC'
from TABLE
Actually I don't understand why FROM_TZ does not accept DATE values whereas almost any other date/timestamp related function accept either DATE or TIMESTAMP value as input.
Note, the default output display format of this query is defined by current user session NLS_TIMESTAMP_TZ_FORMAT setting. If you are not satisfied with the output format, either change NLS_TIMESTAMP_TZ_FORMAT setting by executing ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = '...' or use TO_CHAR function to set output format explicitly.
Instead of
... AT TIME ZONE 'UTC'
you can also use
SYS_EXTRACT_UTC(...)
The upper returns a TIMESTAMP WITH TIME ZONE value, the second one returns a TIMESTAMP value.
Would this do any good?
SQL> select from_tz(cast (sysdate as timestamp), 'UTC') result from dual;
RESULT
---------------------------------------------------------------------------
27.09.20 10:59:28,000000 UTC
Or, in your case
select from_tz(cast (hire_date as timestamp), 'UTC' from dual
No need to apply any format mask to hire_date as it is a DATE datatype (at least, that's what you said).
You use the word "convert" which can mean one of two things:
change the data type, which is what FROM_TZ does
change the value from one time zone to another, which FROM_TZ does not do.
You didn't give your expected output, so we may misunderstand.
To change the data type:
with data(dte) as (
select date '2019-04-30' + interval '12' hour from dual
)
select from_tz(cast(dte as timestamp), 'America/Los_Angeles') from data
FROM_TZ(CAST(DTEASTIMESTAMP),'AMERICA/LOS_ANGELES')
30-APR-19 12.00.00.000000 PM AMERICA/LOS_ANGELES
To get the simultaneous datetime value in UTC:
with data(dte) as (
select date '2019-04-30' + interval '12' hour from dual
)
select cast(sys_extract_utc(from_tz(cast(dte as timestamp), 'America/Los_Angeles')) as date) from data
CAST(SYS_EXTRACT_UTC(FROM_TZ(CAST(DTEASTIMESTAMP),'AMERICA/LOS_ANGELES'))ASDATE)
2019-04-30 19:00:00

Hours and minutes between 2 incorrectly formatted datetimes

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

How to convert date : Sep 26 00:15:00 2020 in YYYY/MM/DD HH24:MI:SS' format in oracle sql

Error while converting
select to_date('Sep 26 00:15:00','DD/MM/YYYY HH24:MI:SS') from dual ;
ORA-01841: (full) year must be between -4713 and +9999, and not be 0 .
Looking for solutions
How? By providing correct format masks, of course.
SQL> select
2 to_char(
3 to_date('Sep 26 00:15:00 2020', 'Mon dd hh24:mi:ss yyyy'),
4 'yyyy/mm/dd hh24:mi:ss'
5 ) result
6 from dual;
RESULT
-------------------
2020/09/26 00:15:00
SQL>
With TO_DATE(), you want to convert a string - 'Sep 26 00:15:00' to an Oracle DATE type - that is a type that counts, internally, the number of seconds since an epoch date.
In Unix, that would be '1970-01-01 00:00:00', in some other databases I know '2000-01-01 00:00:00'. I don't know about Oracle.
So you convert the string: 'Sep 26 00:15:00'. That is: the three-letter English month name abbreviation, a space, the day as two digits, a space, two digits for the 24hour-notated hour, a colon, two digits for the minutes, another colon, and two digits for the second. Nothing for the year, to be precise. The second parameter of TO_DATE() must describe that format. It would therefore be: 'Mon DD HH24:MI:SS' .
The second parameter you use makes absolutely no sense in this context. You could, if you want to play, use it to re-format the converted DATE type, back to a string, in the ISO format, using TO_CHAR():
SELECT
TO_CHAR(
TO_DATE('Sep 26 00:15:00','Mon DD HH24:MI:SS')
, 'YYYY-MM-DD HH24:MI:SS'
)
FROM dual;

Get today's date - Different timezone

I just wanted to know whether the following SQL is good to convert US server time to Thailand date. As we have 12 hours difference in the time, and TH time is ahead of U.S time
SELECT TO_DATE(
TO_CHAR(
SYSTIMESTAMP AT TIME ZONE 'Asia/Bangkok', 'yyyy-mm-dd',
'NLS_DATE_LANGUAGE = american'), 'yyyy-mm-dd') AS TODAY
FROM dual;
It works perfectly fine. But are there any other better way to convert timestamp of server from one timezone to another as I need to compare today's date based on this result in my outer SQL.
You could CAST the timestamp to your desired timezone.
For example,
SQL> WITH data AS (
2 SELECT SYSTIMESTAMP AT TIME ZONE 'Asia/Bangkok' tm_bangkok FROM dual
3 )
4 SELECT tm_bangkok,
5 CAST(tm_bangkok AT TIME ZONE 'EST' AS TIMESTAMP) tm_est
6 FROM data;
TM_BANGKOK TM_EST
--------------------------------------------- ----------------------------
03-NOV-15 12.54.18.951000 PM ASIA/BANGKOK 03-NOV-15 12.54.18.951000 AM
There is no reason to cast a TIMESTAMP to CHAR and then back to TIMESTAMP again. Simply do
SELECT SYSTIMESTAMP AT TIME ZONE 'Asia/Bangkok' AS TODAY
FROM dual;

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