I am recovering the insert from a log file after the application was unable to insert it.
For security reasons, unfortunately I can't put the insert here.
I need to insert some data but I'm having problems with my insert with the date.
How should i convert this date 'Tue Dec 31 12:28:59 BRT 2019' to be able to insert in a date column.
[]´s
A variation on #OldProgrammer's replace approach is to embed the 'BRT' as a character literal in the format mask:
select to_date('Tue Dec 31 12:28:59 BRT 2019',
'DY MON DD HH24:MI:SS "BRT" YYYY',
'NLS_DATE_LANGUAGE=ENGLISH') as result
from dual;
RESULT
-------------------
2019-12-31 12:28:59
I've included the optional third argument to to_date() so that day and month names are always interpreted in English; otherwise the session settings would be used, which could cause it to fail.
I know you aren't interested in the time zone, but if you did want to take that into account, you're still a bit stuck as the abbreviation BRT can't be translated to a single region or offset.
With a limited range of abbreviations that are unambiguous to you, you could go back to replace() to substitute the region name instead, e.g.:
select to_timestamp_tz(replace('Tue Dec 31 12:28:59 BRT 2019', 'BRT', 'America/Sao_Paulo'),
'DY MON DD HH24:MI:SS TZR YYYY',
'NLS_DATE_LANGUAGE=ENGLISH') as ts_result,
cast(to_timestamp_tz(replace('Tue Dec 31 12:28:59 BRT 2019', 'BRT', 'America/Sao_Paulo'),
'DY MON DD HH24:MI:SS TZR YYYY',
'NLS_DATE_LANGUAGE=ENGLISH') as date) as date_result,
to_timestamp_tz(replace('Tue Dec 31 12:28:59 BRT 2019', 'BRT', 'America/Sao_Paulo'),
'DY MON DD HH24:MI:SS TZR YYYY',
'NLS_DATE_LANGUAGE=ENGLISH') at time zone 'UTC' as utc_ts_result,
cast(to_timestamp_tz(replace('Tue Dec 31 12:28:59 BRT 2019', 'BRT', 'America/Sao_Paulo'),
'DY MON DD HH24:MI:SS TZR YYYY',
'NLS_DATE_LANGUAGE=ENGLISH') at time zone 'UTC' as date) as utc_date_result
from dual;
TS_RESULT DATE_RESULT UTC_TS_RESULT UTC_DATE_RESULT
--------------------------------------- ------------------- ------------------------- -------------------
2019-12-31 12:28:59.0 AMERICA/SAO_PAULO 2019-12-31 12:28:59 2019-12-31 14:28:59.0 UTC 2019-12-31 14:28:59
This is slightly simplified by not having to worry about DST here. But as you can see you can then convert easily to another time zone if needed.
This seems to work:
select to_date(replace('Tue Dec 31 12:28:59 BRT 2019','BRT',''),'DY MON DD HH24:MI:SS YYYY') from dual
Related
How to convert varchar Thu Sep 02 16:29:11 UTC 2021 to the timestamp in the snowflake database?
SELECT TO_TIMESTAMP_NTZ('Thu Sep 02 16:29:11 UTC 2021', 'DY MON DD HH24:MI:SS UTC YYYY');
For reference, here is a link to the documentation on the "parts".
https://docs.snowflake.com/en/sql-reference/functions-conversion.html
I'm using snowflake dates.
I have date in weird pattern (output from database):
Wed Apr 21 2021 22:11:32 GMT+0300 (Israel Daylight Time)
I need to parse it as datetime- YY-MM-DD HH:MM:SS.
if I try this out:
SELECT TO_TIMESTAMP_NTZ('Wed Apr 21 2021 22:11:32 GMT+0300 (Israel Daylight Time)', 'YY:MM:DD
HH:MM:SS')
I get this error:
SQL Error [100096] [22007]: Can't parse 'Wed Apr 21 2021 22:11:32 GMT+0300 (Israel Daylight Time)' as
timestamp with format 'YY:MM:DD HH:MM:SS'
and so on in every function I tried!!
(TO_TIMESTAMP_NTZ, TO_TIMESTAMP_LTZ, TO_TIMESTAMP_TZ, TO_TIMESTAMP, TO_DATETIME, TO_DATE, TO_TIME).
any idea?
Using the values at Timestamp Formats, and trimming the string down we can get the following working
SELECT TO_TIMESTAMP_NTZ('Wed Apr 21 2021 22:11:32', 'DY MON DD YYYY HH:MM:SS');
adding the timezone back in with
SELECT TO_TIMESTAMP_NTZ('Wed Apr 21 2021 22:11:32 GMT+0300', 'DY MON DD YYYY HH:MM:SS GMTTZHTZM');
this works, but gives a NoTimeZone value, when the value has a timezone, so purhaps NTZ is not what you wanted.
But the (Israel Daylight Time) part is throwing us for a loop, so lets get rid of that with a REGEX_SUBSTR
SELECT 'Wed Apr 21 2021 22:11:32 GMT+0300 (Israel Daylight Time)' as in_str
,REGEXP_SUBSTR( in_str , '(.*) \\(',1,1,'c',1) as regex_str
,TO_TIMESTAMP_NTZ(regex_str, 'DY MON DD YYYY HH:MM:SS GMTTZHTZM') as time
;
gives:
IN_STR
Wed Apr 21 2021 22:11:32 GMT+0300 (Israel Daylight Time)
REGEX_STR
Wed Apr 21 2021 22:11:32 GMT+0300
TIME
2021-11-21 22:00:32.000
Can you help to get an answer in hive?
Source: Sat Nov 25 2017
Output should be: 2017-11-25 00:00:00
I am using the below logic but it is not working
select from_unixtime(unix_timestamp(substr('Sat Nov 25 2017',5,15),'MMM DD YYYY'),'YYYY-MM-DD');
Regards,
mahesh
You were not too far. Case of the formatting pattern matters!
SELECT from_unixtime(unix_timestamp(substr('Sat Nov 25 2017',5,15), 'MMM dd yyyy'), 'yyyy-MM-dd HH:mm:ss');
Output
2017-11-25 00:00:00
select TO_TIMESTAMP_TZ('1965-08-01 00:00:00.0','Dy Mon DD HH:MM:ss TZD YYYY') from dual;
i have data in wrong format in varchar column as below mentioned.
1973-12-12 00:00:00.0
2003-05-14 00:00:00.0
1950-05-01 00:00:00.0
Fri Jul 01 00:00:00 PDT 1977
Sun Feb 01 00:00:00 PST 2015
Wed May 14 00:00:00 PDT 2003
I want to keep all date in same format as below but not able to convert.
Fri Jul 01 00:00:00 PDT 1977
Sun Feb 01 00:00:00 PST 2015
Wed May 14 00:00:00 PDT 2003
When adding 'Dy Mon DD HH:MM:ss TZD YYYY' format then getting exception not valid date format due to TZD.
Can any one help me to convert this date and keep in same format through update query.
Storing dates or timestamps as strings is not a good idea. You should make your columns the correct datatype for the data they will hold. As well as allowing Oracle to be more efficient, it prevents you storing invalid data.
However, if you just want to convert strings like '1965-08-01 00:00:00.0' to 'Tue Aug 01 00:00:00 PDT 2000' so they are all in the same string format you can convert those values to timestamps with to_timestamp(), specify which time zone they represent with from_tz(), and then convert them back to string in the format you want. With a demo table t built with your sample data:
update t set str = to_char(from_tz(to_timestamp(str, 'YYYY-MM-DD HH24:MI:SS.FF'),
'America/Los_Angeles'), 'Dy Mon DD HH24:MI:SS TZD YYYY')
where str not like '%PDT%' and str not like '%PST%';
3 rows updated.
select * from t;
STR
----------------------------
Wed Dec 12 00:00:00 PST 1973
Wed May 14 00:00:00 PDT 2003
Mon May 01 00:00:00 PDT 1950
Fri Jul 01 00:00:00 PDT 1977
Sun Feb 01 00:00:00 PST 2015
Wed May 14 00:00:00 PDT 2003
6 rows selected
You need to apply a filter so it ignores any rows that are already in the target format, since those would error. Here I've excluded any that contain PDT or PST. If you have other formats you haven't shown you could use regexp_like() to look for rows that exactly match a specific format instead.
More generally, to convert any of your strings to actual timestamps you can create a function that tries various formats and returns the first one that successfully converts, by trapping exceptions. A simple brute force approach might be:
create or replace function my_to_timestamp_tz(p_str varchar2)
return timestamp with time zone as
begin
-- try each expected pattern in turn
begin
return to_timestamp_tz(p_str, 'Dy Mon DD HH24:MI:SS TZD YYYY');
exception
when others then
null;
end;
begin
-- unspecified TZ; this assumes same as server
return to_timestamp_tz(p_str, 'YYYY-MM-DD HH24:MI:SS.FF');
exception
when others then
null;
end;
-- maybe throw an exception if no conversions worked
return null;
end;
/
PDT/PST isn't always recognised; I have two DBs that I thought were built the same but one allows that and other throws "ORA-01857: not a valid time zone". If you see that too you can work around it by treating the TZD value as a fixed string and specifying which region it represents:
-- if your DB doesn't recognise PDT/PST then force them to a region:
begin
return from_tz(to_timestamp_tz(p_str, 'Dy Mon DD HH24:MI:ss "PDT" YYYY'),
'America/Los_Angeles');
exception
when others then
null;
end;
begin
return from_tz(to_timestamp_tz(p_str, 'Dy Mon DD HH24:MI:ss "PST" YYYY'),
'America/Los_Angeles');
exception
when others then
null;
end;
-- other time zone abbreviations and matching regions if you expect any
Using that function:
with t (str) as (
select '1973-12-12 00:00:00.0' from dual
union all select '2003-05-14 00:00:00.0' from dual
union all select '1950-05-01 00:00:00.0' from dual
union all select 'Fri Jul 01 00:00:00 PDT 1977' from dual
union all select 'Sun Feb 01 00:00:00 PST 2015' from dual
union all select 'Wed May 14 00:00:00 PDT 2003' from dual
)
select str, my_to_timestamp_tz(str) as converted
from t;
STR CONVERTED
---------------------------- ----------------------------------------------------
1973-12-12 00:00:00.0 1973-12-12 00:00:00 Europe/London
2003-05-14 00:00:00.0 2003-05-14 00:00:00 Europe/London
1950-05-01 00:00:00.0 1950-05-01 00:00:00 Europe/London
Fri Jul 01 00:00:00 PDT 1977 1977-07-01 00:00:00 America/Los_Angeles
Sun Feb 01 00:00:00 PST 2015 2015-02-01 00:00:00 America/Los_Angeles
Wed May 14 00:00:00 PDT 2003 2003-05-14 00:00:00 America/Los_Angeles
Notice that the first three assume a time zone, and because I'm running this in the UK pick London. If that isn't going to give the right result for you and you know those always represent a specific time zone, you can can specify that zone by changing the last block in the function to do:
begin
-- unspecified TZ; assume from a specific region
return from_tz(to_timestamp(p_str, 'YYYY-MM-DD HH24:MI:SS.FF'),
'America/Los_Angeles');
exception
...
which will then get:
STR CONVERTED
---------------------------- ----------------------------------------------------
1973-12-12 00:00:00.0 1973-12-12 00:00:00 America/Los_Angeles
2003-05-14 00:00:00.0 2003-05-14 00:00:00 America/Los_Angeles
1950-05-01 00:00:00.0 1950-05-01 00:00:00 America/Los_Angeles
Fri Jul 01 00:00:00 PDT 1977 1977-07-01 00:00:00 America/Los_Angeles
Sun Feb 01 00:00:00 PST 2015 2015-02-01 00:00:00 America/Los_Angeles
Wed May 14 00:00:00 PDT 2003 2003-05-14 00:00:00 America/Los_Angeles
If you really want to you can convert the generated timestamps back to strings, but I'd really recommend you store them as the right data type
I have a query which use a date
I work with oracle
but I have a problem in format of date
when I run my query I have an error
this my query test:
select NUM_REQUEST,
from REQUEST_TEST
where REQUEST_DATE between TO_DATE('Thu Nov 07 00:00:00 CET 2013','MM/dd/yyyy hh:mm:ss a') and TO_DATE('Mon Dec 23 00:00:00 CET 2013','MM/dd/yyyy hh:mm:ss a'))
I have an error in foramt of date using to_date function
when I try with this query and I have a correct result
select NUM_REQUEST,
from REQUEST_TEST
where REQUEST_DATE between to_timestamp_tz('Thu Nov 07 00:00:00 CET 2013','Dy Mon dd hh24:mi:ss TZR yyyy') and to_timestamp_tz('Mon Dec 23 00:00:00 CET 2013','Dy Mon dd hh24:mi:ss TZR yyyy'))
but when I test in my application with :
String sqlQuery = "select NUM_REQUEST, from REQUEST_TEST" +
" where REQUEST_DATE between to_timestamp_tz('Thu Nov 07 00:00:00 CET 2013','Dy Mon dd hh24:mi:ss TZR yyyy') and to_timestamp_tz('Mon Dec 23 00:00:00 CET 2013','Dy Mon dd hh24:mi:ss TZR yyyy')) ";
Query query = this.getSession().createSQLQuery(sqlQuery);
I have this error :
ORA-01846: ce n'est pas un jour de semaine valide
org.hibernate.exception.DataException: could not execute query
I have for example in my column REQUEST_DATE this data 29-NOV-13 and when I edit this column I have this format for example : friday, 29 Novembre 2013 00:00:00 o'clock CET
As others have said, your date format must match your date string. Have a look at Oracle Datetime Format Elements for all possible elements.
Also, since there is a timezone in your string you need to cast it to timestamp datatype and not date. So, you need to use TO_TIMESTAMP_TZ function.
So, to answer you question it should be something like this.
to_timestamp_tz('Thu Nov 07 00:00:00 CET 2013','Dy Mon dd hh24:mi:ss TZR yyyy')
Looks like your language setting is french. So you need to supply the month/day accordingly.
to_timestamp_tz('Jeu. Nov. 07 00:00:00 CET 2013','Dy Mon dd hh24:mi:ss TZR yyyy')
or you should explicitly change the language to English, which you can do in the function call itself.
to_timestamp_tz('Thu Nov 07 00:00:00 CET 2013',
'Dy Mon dd hh24:mi:ss TZR yyyy',
'nls_date_language = ENGLISH')
Probably you need this. And I believe you get this date format from UNIX.
You can also try formatting the date from Unix if so.
select to_timestamp_tz('Thu Nov 07 00:00:00 EDT 2013','Dy Mon DD HH24:MI:SS TZD YYYY') from dual;
The closest one I can think of would be:
select NUM_REQUEST,
from REQUEST_TEST
where REQUEST_DATE Between TO_TIMESTAMP_TZ('Thu Nov 07 00:00:00 CET 2013','DY MON DD HH24:MI:SS TZR YYYY' ) And TO_TIMESTAMP_TZ('Mon Dec 23 00:00:00 CET 2013','DY MON DD HH24:MI:SS TZR YYYY')
Be careful with the month abbreviations, as they depend on your locale language settings. For example, December is Dec in English but Dic in Spanish.
Update: your problem with ORA-01846 is related as well to your locale language settings. You need to use the abbreviation corresponding to your language. For example, I guess that for French the abbreviation for Friday (Vendredi in French) would be Ven.