Covert ZULU time to PST - hive

I am trying to covert start_time which is in yulu format to pst.
Start_time sample: 2020-02-04T04:36:42:211Z
from_unixtime(unix_timestamp(sub string(start_time,1,17),'yyyy-MM-ddThh:mm:ss.SSSZ),'yyyy-MM-dd hh:mm:ss)
But I am getting output as NULL.
Please help.

Escape T, Z in the string. Note the use of double-quotes for the pattern and T and Z are escaped with a single-quote.
select from_unixtime(unix_timestamp('2020-02-04T04:36:42:211Z',"yyyy-MM-dd'T'HH:mm:ss:SSS'Z'")
,'yyyy-MM-dd HH:mm:ss')
Also, you don't need a substring as you are matching the pattern for the full string.

It is better to use FROM_UTC_TIMESTAMP because UNIX_TIMESTAMP returns seconds, you will lose the millisecond component of your timestamp.
FROM_UTC_TIMESTAMP(UNIX_TIMESTAMP(2020-02-04T04:36:42:211Z, "yyyy-MM-dd'T'hh:mm:ss.SSS'Z'"), 'PST')
Sometime it might possible that because of "T" and "Z" our result get distorted.In that case we can use:
from_utc_timestamp(CONCAT(substring('2020-02-04T04:36:42:211Z',1,10)," ",substring('2020-02-04T04:36:42:211Z',12,12)),'PST')

Related

casting string to date postgresql

Using postgres 14
I have a timestamp something like this 2011-04-26T05:04:11Z. Its in UTC time
I tried converting it to a postgres timestamp using this function and i get a wrong result
2022-04-26 00:04:11-07. The time part seems messed up.
This is the query i have
select to_TIMESTAMP('2011-04-26T05:04:11Z','YYYY-MM-DDTHH:MI:SS')
If you just want to convert the string to a Postgres timestamp then:
select '2011-04-26T05:04:11Z'::timestamptz;
04/25/2011 22:04:11 PDT
The output will depend on the DateStyle setting.
To get your example to work then:
select to_TIMESTAMP('2011-04-26T5:04:11Z','YYYY-MM-DD"T"HH24:MI:SS');
to_timestamp
-------------------------
04/26/2011 05:04:11 PDT
Note the "T" this causes it to be ignored as that seems to be what is causing the issues. Not certain, but probably related to Postgres ISO format using a space instead of T. Quoting characters to be ignored comes from Formatting function:
Tip
Prior to PostgreSQL 12, it was possible to skip arbitrary text in the input string using non-letter or non-digit characters. For example, to_timestamp('2000y6m1d', 'yyyy-MM-DD') used to work. Now you can only use letter characters for this purpose. For example, to_timestamp('2000y6m1d', 'yyyytMMtDDt') and to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"') skip y, m, and d.
There is no provision for a time zone abbreviation in to_timestamp so the Z will be ignored and the timestamp will be in local time with the same time value. That is why I made my first suggestion using the timestamptz cast.
Two ways to deal with time zone:
One:
select to_TIMESTAMP('2011-04-26T5:04:11Z','YYYY-MM-DD"T"HH24:MI:SS')::timestamp AT time zone 'UTC';
timezone
-------------------------
04/25/2011 22:04:11 PDT
Two:
select to_TIMESTAMP('2011-04-26T5:04:11+00','YYYY-MM-DD"T"HH24:MI:SS+TZH');
to_timestamp
-------------------------
04/25/2011 22:04:11 PDT

timestamp conversion for below query

I have these data '2019-12-19T01:39:29.6941632Z' as varchar2 datatype
i have to replace the T and Z and also to convert the datatype to timestamp
I tried this query but won't work
to_timestamp(replace(replace('2019-12-19T01:39:29.6941632Z','T',''),'Z'),'YYYY.MM.DD:HH24:MI:SS')
Please help me
My proposal would be this one:
CAST(TO_TIMESTAMP_TZ('2019-12-19T01:39:29.6941632Z', 'YYYY-MM-DD"T":HH24:MI:SS.FFTZR') AS TIMESTAMP)
As a slight variation on #Wernfried's conversion, since you aren't using the time zone information you can treat the fixed Z as a character literal too, like the fixed T. Then you can use to_timestamp(), and don't need to cast():
TO_TIMESTAMP('2019-12-19T01:39:29.6941632Z', 'YYYY-MM-DD"T"HH24:MI:SS.FF"Z"')
The YYYY, MM, DD, HH24, MI, SS and FF parts of the format mask are as described in the documentation. The "T" and "Z" are character literals so the function knows not to try to interpret them as part of the timestamp value; which means you don't need to remove/replace them. And the overall format mask matches the source string - by default Oracle is forgiving of using the wrong separators (like . instead of -) but it's better to use the correct expected values anyway.
e.g.:
SELECT TO_TIMESTAMP('2019-12-19T01:39:29.6941632Z', 'YYYY-MM-DD"T"HH24:MI:SS.FF"Z"')
FROM DUAL;
19-DEC-19 01.39.29.694163200 AM
(and you can then handle or format the timestamp however you want)
You need to fix the replace(). And use the correct format.
This works:
select to_timestamp(replace(replace('2019-12-19T01:39:29.6941632Z', 'T', ''), 'Z', ''), 'YYYY-MM-DDHH24:MI:SS.FF')
from dual
Here is a db<>fiddle.

How to convert this specific timestamp format to UTC in Redshift?

I have timestamp strings that look something like the example here:
2017-07-12T01:51:12.732-0600. Is there any function/combination of functions I can use this to convert this to UTC accurately?
The output should be 2017-07-12 07:51:12.732000. I've tried using to_timestamp and convert_timezone. Obviously, the latter failed, but so did the former and I'm at my wit's end. Help?
you can convert the string directly to timestamp and then set source timezone in convert_timezone function like this (note, offset sign is the opposite to timezone):
select convert_timezone('UTC+06','utc','2017-07-12T01:51:12.732-0600'::timestamp)
if -0600 part is varying you can construct 'UTC+06' part dynamically like this
with times as (
select '2017-07-12T01:51:12.732-0600'::varchar(28) as ts_col
)
select convert_timezone('utc'+(substring(ts_col from 24 for 3)::integer*(-1))::varchar(3),'utc',ts_col::timestamp)
from times

How to change date format in hive?

My table in hive has a filed of date in the format of '2016/06/01'. but i find that it is not in harmory with the format of '2016-06-01'.
They can not compare for instance.
Both of them are string .
So I want to know how to make them in harmory and can compare them. Or on the other hand, how to change the '2016/06/01' to '2016-06-01' so that them can compare.
Many thanks.
To convert date string from one format to another you have to use two date function of hive
unix_timestamp(string date, string pattern) convert time string
with given pattern to unix time stamp (in seconds), return 0 if
fail.
from_unixtime(bigint unixtime[, string format]) converts the
number of seconds from unix epoch (1970-01-01 00:00:00 UTC) to a
string representing the timestamp of that moment in the current
system time zone.
Using above two function you can achieve your desired result.
The sample input and output can be seen from below image:
The final query is
select from_unixtime(unix_timestamp('2016/06/01','yyyy/MM/dd'),'yyyy-MM-dd') from table1;
where table1 is the table name present in my hive database.
I hope this help you!!!
Let's say you have a column 'birth_day' in your table which is in your format,
you should use the following query to convert birth_day into the required format.
date_Format(birth_day, 'yyyy-MM-dd')
You can use it in a query in the following way
select * from yourtable
where
date_Format(birth_day, 'yyyy-MM-dd') = '2019-04-16';
Use :
unix_timestamp(DATE_COLUMN, string pattern)
The above command would help convert the date to unix timestamp format which you may format as you want using the Simple Date Function.
Date Function
cast(to_date(from_unixtime(unix_timestamp(yourdate , 'MM-dd-yyyy'))) as date)
here is my solution (for string to real Date type):
select to_date(replace('2000/01/01', '/', '-')) as dt ;
ps:to_date() returns Date type, this feature needs Hive 2.1+; before 2.1, it returns String.
ps2: hive to_date() function or date_format() function , or even cast() function, cannot regonise the 'yyyy/MM/dd' or 'yyyymmdd' format, which I think is so sad, and make me a little crazy.

In Oracle, convert number(5,10) to date

When ececute the following SQL syntax in Oracle, always not success, please help.
40284.3878935185 represents '2010-04-16 09:18:34', with microsecond.
an epoch date of 01 January 1900 (like Excel).
create table temp1 (date1 number2(5,10));
insert into temp1(date1) values('40284.3878935185');
select to_date(date1, 'yyyy-mm-dd hh24:mi:ssxff') from temp1
Error report: SQL Error: ORA-01861: literal does not match format
string
01861. 00000 - "literal does not match format string"
*Cause: Literals in the input must be the same length as literals in
the format string (with the exception of leading whitespace). If the
"FX" modifier has been toggled on, the literal must match exactly,
with no extra whitespace.
*Action: Correct the format string to match the literal.
Thanks to Mark Bannister
Now the SQL syntax is:
select to_char(to_date('1899-12-30','yyyy-mm-dd') +
date1,'yyyy-mm-dd hh24:mi:ss') from temp1
but can't fetch the date format like 'yyyy-mm-dd hh24:mi:ss.ff'. Continue look for help.
Using an epoch date of 30 December 1899, try:
select to_date('1899-12-30','yyyy-mm-dd') + date1
Simple date addition doesn't work with timestamps, at least if you need to preserve the fractional seconds. When you do to_timestamp('1899-12-30','yyyy-mm-dd')+ date1 (in a comment on Mark's answer) the TIMESTAMP is implicitly converted to a DATE before the addition, to the overall answer is a DATE, and so doesn't have any fractional seconds; then you use to_char(..., '... .FF') it complains with ORA-01821.
You need to convert the number of days held by your date1 column into an interval. Fortunately Oracle provides a function to do exactly that, NUMTODSINTERVAL:
select to_timestamp('1899-12-30','YYYY-MM-DD')
+ numtodsinterval(date1, 'DAY') from temp3;
16-APR-10 09.18.33.999998400
You can then display that in your desired format, e.g. (using a CTE to provide your date1 value):
with temp3 as ( select 40284.3878935185 as date1 from dual)
select to_char(to_timestamp('1899-12-30','YYYY-MM-DD')
+ numtodsinterval(date1, 'DAY'), 'YYYY-MM-DD HH24:MI:SSXFF') from temp3;
2010-04-16 09:18:33.999998400
Or to restrict to thousandths of a second:
with temp3 as ( select 40284.3878935185 as date1 from dual)
select to_char(to_timestamp('1899-12-30','YYYY-MM-DD')+
+ numtodsinterval(date1, 'DAY'), 'YYYY-MM-DD HH24:MI:SS.FF3') from temp3;
2010-04-16 09:18:33.999
An epoch of 1899-12-30 sounds odd though, and doesn't correspond to Excel as you stated. It seems more likely that your expected result is wrong and it should be 2010-04-18, so I'd check your assumptions. Andrew also makes some good points, and you should be storing your value in the table in a TIMESTAMP column. If you receive data like this though, you still need something along these lines to convert it for storage at some point.
Don't know the epoch date exactly, but try something like:
select to_date('19700101','YYYYMMDD')+ :secs_since_epoch/86400 from dual;
Or, cast to timestamp like:
select cast(to_date('19700101', 'YYYYMMDD') + :secs_since_epoch/86400 as timestamp with local time zone) from dual;
I hope this doesn't come across too harshly, but you've got to totally rethink your approach here.
You're not keeping data types straight at all. Each line of your example misuses a data type.
TEMP1.DATE1 is not a date or a varchar2, but a NUMBER
you insert not the number 40284.3878935185, but the STRING >> '40284.3878935185' <<
your SELECT TO_DATE(...) uses the NUMBER Temp1.Date1 value, but treats it as a VARCHAR2 using the format block
I'm about 95% certain that you think Oracle transfers this data using simple block data copies. "Since each Oracle date is stored as a number anyway, why not just insert that number into the table?" Well, because when you're defining a column as a NUMBER you're telling Oracle "this is not a date." Oracle therefore does not manage it as a date.
Each of these type conversions is calculated by Oracle based on your current session variables. If you were in France, where the '.' is a thousands separator rather than a radix, the INSERT would completely fail.
All of these conversions with strings are modified by the locale in which Oracle thinks your running. Check dictionary view V$NLS_PARAMETERS.
This gets worse with date/time values. Date/time values can go all over the map - mostly because of time zone. What time zone is your database server in? What time zone does it think you're running from? And if that doesn't spin your head quite enough, check out what happens if you change Oracle's default calendar from Gregorian to Thai Buddha.
I strongly suggest you get rid of the numbers ENTIRELY.
To create date or date time values, use strings with completely invariant and unambiguous formats. Then assign, compare and calculate date values exclusively, e.g.:
GOODFMT constant VARCHAR2 = 'YYYY-MM-DD HH24:MI:SS.FFF ZZZ'
Good_Time DATE = TO_DATE ('2012-02-17 08:07:55.000 EST', GOODFMT);