This question already has answers here:
Convert timestamp to date in Oracle SQL
(9 answers)
Closed 2 years ago.
i have to convert different timezone string to date. in my table, i have column defined as varchar2. which contains data as below. i need to convert to one time zone(exampple to central time) and extract date from that. i tried different ways but getting invalid month error or not date. ANy suggestions from your end?
1/16/2020 6:28:44 AM -08:00
11/8/2019 3:20:30 AM -05:00
10/25/2019 6:08:21 PM +05:30
I believe you first need to convert it to timestamp with timezone ad then cast it to date:
select CAST(to_timestamp_tz (dat_col, 'MM/DD/YYYY HH12:MI:SS AM TZH:TZM' ) AS DATE)
from test
here is a demo
This will turn your data into specific timezone :
select
to_timestamp_tz(dat_col, 'MM/DD/YYYY HH12:MI:SS AM TZH:TZM')at time zone 'Europe/Moscow'
from test
Then you can cast that :
select
CAST
(to_timestamp_tz(dat_col, 'MM/DD/YYYY HH12:MI:SS AM TZH:TZM')at time zone 'Europe/Moscow'
AS DATE)
from test
Please provide your expected results for more accurate code...
Related
Source data has different formats
I am working with a nested JSON table and the created_at field cannot be cast to a timestamp.
Here is in essence what should work:
SELECT
TO_TIMESTAMP(json_data:created_at::VARCHAR, 'mm/dd/yyyy HH:MI:SS AM TZH:TZM') AS custom_date_cast
, TO_TIMESTAMP(json_data:created_at::VARCHAR) AS default_date_cast
FROM my_table
Reason why there is the two fields is because we have dates coming in with this format: 11/21/2022 12:25:30 PM +00:00 (custom_date_cast) and this format 2023-02-07T15:50:09.8385748+00:00 (default_date_cast).
In theory I would create a CASE WHEN to catch the two different cases, alias it to created_at and be done with it. However there are some dates that apparently fit neither of these casts.
What I tried
Here's such an example I retrieved using this query:
SELECT
TRY_TO_TIMESTAMP(json_data:created_at::VARCHAR, 'mm/dd/yyyy HH:MI:SS AM TZH:TZM') AS custom_date_cast
, TRY_TO_TIMESTAMP(json_data:created_at::VARCHAR) AS default_date_cast
, json_data:created_at::VARCHAR AS created_at
FROM my_table
WHERE
TRY_TO_TIMESTAMP(json_data:created_at::VARCHAR, 'mm/dd/yyyy HH:MI:SS AM TZH:TZM') IS NULL
AND TRY_TO_TIMESTAMP(json_data:created_at::VARCHAR) IS NULL
Here's one such result: 4/8/2022 12:49:44 PM +00:00. As you will notice, it is identical to one such example that does work such as: 1/22/2022 4:01:52 PM +00:00.
If I use TO_TIMESTAMP() instead, I get this error for some entries (full breakdown below):
SQL Error [100096] [22007]: Can't parse '4/8/2022 12:49:44 PM +00:00' as timestamp with format 'mm/dd/yyyy HH:MI:SS AM TZH:TZM'
Using this query above I used a COUNT(*) to see how many cases we had with this weird anomaly. The results:
AND
Custom Casting Worked
Custom Casting Failed
Default Casting Worked
0
957
Default Casting Failed
204,588
19,527
This means there are 19,527 entries that cannot be cast either by my custom cast or by the default casting method.
What is even stranger to me is that if I literally copy one of the "non-working" date as an example, then run this SELECT statement it will work just fine:
SELECT
TO_TIMESTAMP('4/8/2022 12:49:44 PM +00:00', 'mm/dd/yyyy HH:MI:SS AM TZH:TZM');
Does anyone have any idea of what could be the problem or what I could try next?
Try creating a Python UDF to parse the dates.
Anaconda already provides in Snowflake "dateutil":
https://github.com/dateutil/dateutil/
It offers what you need:
Generic parsing of dates in almost any string format;
For example:
from dateutil.parser import *
now = parse("Sat Oct 11 17:13:46 UTC 2003")
Docs:
https://dateutil.readthedocs.io/en/stable/parser.html#dateutil.parser.parse
I've tried multiple solutions, but I keep getting errors. I need to create a new column casting VARCHAR to TIMESTAMP that includes AM, PM or -ideally- changes it to 24 hrs format.
VARCHAR format (Start_Date column): 8/3/2022 4:58:49 PM
I found the below solution is some other post, but I'm getting error: 'Format code appears twice'
SELECT itab.*,
TO_TIMESTAMP(Start_Date, 'MM/DD/YYYY HH:MM:SS AM') AS start_TS
FROM db.info_table itab
Please advise.
You have two problems.
MI is the format for minutes, MM is for months (you have it twice, this is why you are getting that error).
Your date/time string has single digit values for month, day, etc. You can use a pretty simple regex for that.
select to_timestamp(regexp_replace('8/3/2022 4:58:49 PM', '\b([0-9])\b', '0\1'), 'MM/DD/YYYY HH:mi:SS AM')
TO_TIMESTAMP returns a TIMESTAMP(6). If you don't want microseconds you can specify the precision using
CAST(RegExp_Replace(start_date, '\b([0-9])\b', '0\1') AS timestamp(0) FORMAT 'MM/DD/YYYYbHH:Mi:SSbT')
All you need is pad day and month in Teradata (as opposed to Oracle etc). m/d/y format has not been implemented.
select '8/3/2022 4:58:49 PM' date1,
to_timestamp(
lpad(strtok(date1,'/',1),2,'0')||'/'||lpad(strtok(date1,'/',2),2,'0')||'/'||strtok(date1,'/',3)
,'mm/dd/yyyy hh24:mi:ss AM'
);
Need help with Oracle SQL Formatting. I have the below code which outputs the data (MINNEEDTIME) in DD-MM-YY format. Need to change this to MM/DD/YYYY HH:MI AM format. Tried TO_CHAR for converting and that threw an error. Any assistance will be appreciated. Thank you
min(case when ve.REASON in ('Need Time', 'WAITING Time') then ve.EVENT_DTIME end) as MINNEEDTIME
You can use TO_CHAR(<date>, <format>) as in:
select to_char(current_date, 'MM/DD/YYYY HH:MI AM') from dual
In your case replace ve.EVENT_DTIME with:
to_char(ve.EVENT_DTIME, 'MM/DD/YYYY HH:MI AM')
In Oracle, a DATE is a binary data type consisting of 7 bytes that represent: century, year-of-century, month, day, hour, minute and second. It ALWAYS contains those components and it is never stored with any human-readable format.
What you are seeing is the client application you are using to access the database receiving the (unformatted) binary data and trying to be helpful and applying its own format to the date.
You need to either:
Explicitly convert the value from a DATE to a string and apply a format using the TO_CHAR function:
TO_CHAR(
min(
case
when ve.REASON in ('Need Time', 'WAITING Time')
then ve.EVENT_DTIME
end
),
'MM/DD/YYYY HH12:MI AM'
) as MINNEEDTIME
Or, you need to change how the client application you are using formats dates. You can either look for the settings/preferences in the application or some applications (for example, SQL*Plus or SQL Developer) will use the NLS_DATE_FORMAT session parameter which you can change using:
ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY HH:MI AM';
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
This question already has answers here:
Convert String ISO-8601 date to oracle's timestamp datatype
(2 answers)
Closed 6 years ago.
Any suggestions on how I can convert a VARCHAR of format 2016-03-24T11:31:31+0100 into timestamp/time zone
"FIELD_YYY" which was obviously once a timestamp with time zone
is fed to "TABLE_XXX" and I have to use this field from this table for my uses.
(I believe the T marks the start of the time part when timestamp is converted to VARCHAR)
I need to convert this back to timestamp/time zone.
select to_timestamp('2016-03-24T11:31:31+0100', 'yyy-mm-dd hh24:mi:ss') from DUAL
No I can't change the "FIELD_YYY" or "TABLE_XXX", WHY? I just can't, that's life... :-(
Use to_timestamp_tz() function, enclose "T" in double quotes in the format string and you are good to go.
select to_timestamp_tz('2016-03-24T11:31:31+0100'
, 'yyyy-mm-dd"T"hh:mi:sstzhtzm') as res
from dual
result:
RES
--------------------------------------
24-MAR-16 11.31.31.000000000 AM +01:00
You can use to_timestamp_tz
select to_timestamp_tz(your_string, 'YYYY-MM-DD HH24:MI:SS TZH:TZM') from dual;
select to_timestamp_tz('2011-05-12 19:04:41.032645 +01:00',
'YYYY-MM-DD"T"HH24:MI:SS TZH:TZM') from dual;