PostgreSQL: Convert MongoDB date format to timestamptz - sql

I have referred to the psql documentation and came up with this query.
SELECT to_timestamp('Tue Aug 30 2016 04:07:13 GMT+0530 (IST)', 'Dy MON DD YYYY HH24:MI:SS');
This date time string Tue Aug 30 2016 04:07:13 GMT+0530 (IST) is what I got from MongoDB printjson(createdAt).
The above postresql doesn't seem to work correctly for all offsets.
I tried this
select to_timestamp('Tue Aug 30 2016 04:07:13 GMT+0530 (IST)', 'Dy MON DD YYYY HH24:MI:SS "GMT"OF "(IST)"');
But I get this error ``ERROR: "TZ"/"tz"/"OF" format patterns are not supported in to_date`.
How to convert to psql timestamptz format from this string Tue Aug 30 2016 04:07:13 GMT+0530 (IST) ?

It looks an ugly wheel and requires such replace for each unrecognized offset, but it works. For your sample replace 'GMT+0530 (IST)' to 'GMT+05:30' and it will be picked up:
t=# select replace('Tue Aug 30 2016 04:07:13 GMT+0530 (IST)','GMT+0530 (IST)','GMT+05:30')::timestamptz;
replace
------------------------
2016-08-30 09:37:13+00
(1 row)
t=# select replace('Tue Aug 30 2016 14:07:13 GMT+0530 (IST)','GMT+0530 (IST)','GMT+05:30')::timestamptz;
replace
------------------------
2016-08-30 19:37:13+00
(1 row)
update: depending on your timezone result can be confusing:
t=# set timezone TO 'GMT-5:30'; SET
t=# select replace('Tue Aug 30 2016 14:07:13 GMT+0530 (IST)','GMT+0530 (IST)','GMT+05:30')::timestamptz;
replace
---------------------------
2016-08-31 01:07:13+05:30
(1 row)
to check if it is right, use:
t=# select replace('Tue Aug 30 2016 14:07:13 GMT+0530 (IST)','GMT+0530 (IST)','GMT+05:30')::timestamptz at time zone 'UTC';
timezone
---------------------
2016-08-30 19:37:13
(1 row)

Related

PostgresSql - Filtering data between dates which in format like Mon Jun 20 2022 10:04:01 GMT+0530 (India Standard Time)

PostgresSql - Filtering data between dates which in format like Mon Jun 20 2022 10:04:01 GMT+0530 (India Standard Time). I want to filter data between 2 dates
i.stack.imgur.com/Hu91J.jpg

convert Thu Sep 02 16:29:11 UTC 2021 to timestamp in snowflake

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

how to convert long verbal datetime to timestamp (YY-MM-DD HH:MM:SS) in snowflake?

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

presto sql: select the data that before or after a datetime

There is table called t1, and there are columns id, created_at, text, for example, as following table:
id created text
1 Thu Jun 30 01:00:57 +0000 2016 I like this movie1
2 Thu Jun 30 02:59:57 +0000 2016 I like this movie2
3 Thu Jun 30 03:49:57 +0000 2016 I like this movie3
4 Thu Jun 30 04:59:50 +0000 2016 I like this movie4
5 Thu Jun 30 05:39:57 +0000 2016 I like this movie5
6 Thu Jun 30 06:39:57 +0000 2016 I like this movie6
7 Thu Jun 30 06:29:57 +0000 2016 I like this movie6
8 Thu Jun 30 07:09:57 +0000 2016 I like this movie7
9 Thu Jun 30 07:39:57 +0000 2016 I like this movie8
10 Thu Jun 30 08:39:57 +0000 2016 I like this movie9
11 Thu Jun 30 09:39:57 +0000 2016 I like this movie10
12 Thu Jun 30 10:29:57 +0000 2016 I like this movie11
13 Thu Jun 30 11:29:57 +0000 2016 I like this movie12
12 Thu Jun 30 12:29:57 +0000 2016 I like this movie13
I want to select data separated by hour time.
For example, I want to select all the data that hour is less or equal 06, then I want to select the data that hour is more than 07. Since the data of column is datetime form: Thu Jun 30 12:29:57 +0000 2016, I don't know how to deal with this. Thanks for your help!
The sql is presto(presto sql):
select id, created, text from t1 where created_at <= 6
You could use datepart for this if you are using mssql:
select
id,
created,
text
from
t1
where
datepart(hour, created) <= 6
References:
DATEPART (Transact-SQL)
I done it, use the hour(datestamp)can solve it.
select id, created, text from t1 where hour(created_at) <= 6

How to change date format from '1965-08-01 00:00:00.0' to 'Tue Aug 01 00:00:00 PDT 2000' in Oracle

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