Converting epoch time to PST zone in hadoop/hive - hadoop

I want to convert the epoch time into pst time zone.
For example : 1482440069 when I convert to PST, I should get 2016-12-22
Now, when I try this I get proper answer
SELECT from_utc_timestamp('1970-01-01 07:00:00', 'PST');
Also, When I try this, I get proper value
select from_unixtime(cast(1482440069 as bigint), 'yyyy-MM-dd')
o/p : 2016-12-22
But, When I try this query, I get NULL response
select from_utc_timestamp(from_unixtime(cast(1482440069 as bigint), 'yyyy-MM-dd'),'PST') -- Gives NULL response

Use yyyy-MM-dd HH:mm:ss instead of yyyy-MM-dd
hive> select from_utc_timestamp(from_unixtime(cast(1482440069 as bigint), 'yyyy-MM-dd HH:mm:ss'),'PST');
OK
2016-12-22 04:54:29

You can try:
SELECT from_utc_timestamp(cast(from_unixtime('1970-01-01 07:00:00', 'yyyy-MM-dd HH:mm:ss') as bigint) + (time_zone value like -5 or -6 * 3600));

Related

Convert epoch to date in Oracle

Was wondering if anyone could help with precision time conversion.
Sample: 1501646399999 which is GMT: Wednesday, August 2, 2017 3:59:59.999 AM
I used the below query, but it always rounds off to 02-AUG-17 04:00:00. Can anyone please guide me
select TO_TIMESTAMP('1970-01-01 00:00:00.000', 'YYYY-MM-DD hh24:mi:SS.FF3') + ((1/86400000) * 1501646399999)
from dual;
The problem is that you're adding a number to your fixed timestamp, which is causing that timestamp to be implicitly converted to a date - which doesn't have sub-second precision.
If you add an interval instead then it stays as a timestamp:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS.FF3';
select TO_TIMESTAMP('1970-01-01 00:00:00.000', 'YYYY-MM-DD hh24:mi:SS.FF3')
+ numtodsinterval(1501646399999/1000, 'SECOND')
from dual;
TO_TIMESTAMP('1970-01-0
-----------------------
2017-08-02 03:59:59.999
Incidentally, you could slightly simplify your query with a timestamp literal:
select TIMESTAMP '1970-01-01 00:00:00' + numtodsinterval(...)
You may also want to check if you should be declaring that timestamp as being UTC, and converting back to local time zone after adding the epoch value; or leaving it explicitly as UTC but as a timestamp with time zone value. It depends exactly what that number is supposed to represent. (You said it's GMT/UTC, but still...)

How to Add an Interval to a Date in Oracle

I'm trying to get a new date from the product of 'date' + 'time interval'.
Something like this.
'15/02/2016 18:00:00' + '+00 02:00:00.000000'
Expected result:
'15/02/2016 20:00:00'
But using the columns in database.
CREATE TABLE timerest
(
DATE_ASIGN DATE,
TIME_ASIGN INTERVAL DAY(2) TO SECOND(0)
);
Thanks for your help.
You can just add them together:
insert into timerest (date_asign, time_asign)
values (to_date('15/02/2016 18:00:00', 'DD/MM/YYYY HH24:MI:SS'),
to_dsinterval('+00 02:00:00.000000'));
alter session set NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';
select date_asign + time_asign from timerest;
DATE_ASIGN+TIME_ASIGN
---------------------
15/02/2016 20:00:00
This follows the rules for datetime/interval arithmetic: date + interval = date.
If you have a date in DATE format you can simply add the a numeric interval that represents days (for example 1.5 is 1 day and a half)
You can extract from the time interval days and hours and then add them to to you date because, if I remember correctly, you can't add directly them to a date type (maybe to a timestamp type you can)
To extract the days you can use the extract function:
(
extract(second from TIME_ASIGN)/3600)+(extract(hour from TIME_ASIGN)/24)+(extract(day from TIME_ASIGN)/24)
then you add the number to your DATE_ASIGN

ORA-01849: hour must be between 1 and 12

WHERE (ResTRRequest.RequestTime BETWEEN TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), 'YYYY-MM-DD HH24:MI:SS')
AND TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND, 'YYYY-MM-DD HH24:MI:SS'))
I have above where condition in query when i execute it,it gives me hours must be between 1 to 12 due to static date I have given i.e ''2012-12-01 20:10:10', 'HH')' if I put sysdate the its working fine but due to static date it gives me error.
Let's break this down a bit:
WHERE (ResTRRequest.RequestTime
BETWEEN TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), 'YYYY-MM-DD HH24:MI:SS')
AND TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND, 'YYYY-MM-DD HH24:MI:SS'))
In the first place, I don't think you mean this: TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), I think maybe you mean this: TRUNC(TO_DATE('2012-12-01 20:10:10'), 'HH'). The number from 1-12 error comes from the fact that you have an hour of 20 and are trying to convert it into a date with the mask of HH. But as I said I think that's a typo. You can also use a TIMESTAMP literal here rather than TO_DATE():
TRUNC(TIMESTAMP'2012-12-01 20:10:10', 'HH')
Second, and just to get this out of the way, are you storing dates or timestamps as strings? That's not a good idea.
Third, it's not a good idea to use BETWEEN in date comparisons because you can miss the edge cases. It might be better to rewrite this as follows:
WHERE ( ResTRRequest.RequestTime >= TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10'), 'HH'), 'YYYY-MM-DD HH24:MI:SS')
AND ResTRRequest.RequestTime < TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '1' HOUR, 'YYYY-MM-DD HH24:MI:SS') )
Problem is in mask:
TO_DATE('2012-12-01 20:10:10', 'HH')
Replace with this one:
TO_DATE('2012-12-01 20:10:10', 'HH24')
Assuming that ResTRRequest.RequestTime is of a date type, this Where clause will work:
where ResTRRequest.RequestTime
BETWEEN TRUNC(TO_DATE('2015-02-26 20:10:10', 'YYYY-MM-DD HH24:MI:SS'), 'HH')
AND TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND
If you have to compare character representations, keep in mind that you compare in lexicographic order, meaning that prefixes of strings are sorted before their strings! Avoid ensueing complications by using identical formatting models with componnents arranged in the order of decreasing significance. E.g.
TO_CHAR(<whatever>, 'YYYY-MM-DD HH24:MI:SS')
but not
TO_CHAR(<whatever>, 'MM/DD/YYYY HH24:MI:SS')
If the language setting on Oracle is set for using the 12 hours time, this problem will occur when converting the 24 hours time format.
There are two solutions to this :
Convert TIMESTAMP/DATE format in Oracle client
alter session set nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF6';
Convert query to match 24hr format
SELECT * FROM TEST_ WHERE DOB > TRUNC(TIMESTAMP'1970-01-01 20:10:10', 'HH');
or
SELECT * FROM TEST_ WHERE DOB > to_date('1970-01-01 20:00:00','YYYY-MM-DD HH24:MI:SS');
One more thing to watch out for in the case you get this error is the data itself.
I've had date stored in xml tag that I had to parse and convert with TO_DATE with this format specifier 'MM/dd/YYYY HH:MI:SS AM'. SQL broke with "ORA-01849: hour must be between 1 and 12" because some records were written like this: "12/20/2017 16:45:00 PM". Pay attention to 16h and PM specfier...

Using Oracle to_date function for date string with milliseconds

I have to perform some inserts into an Oracle DB. I have some dates
in the following format
'23.12.2011 13:01:001'
Following the documentation I wrote inserts to_date as follows:
to_date('23.12.2011 13:01:01', 'DD.MM.YYYY HH24:MI:SS')
which works properly. Now I have dates with milliseconds with the format
'23.12.2011 13:01:001'
I've tried the following:
to_date('23.12.2011 13:01:001', 'DD.MM.YYYY HH24:MI:SSFF3')
which is incorrect (delivers an error 01821. 00000 - "date format not recognized").
Which "String" should I use for this format with milliseconds?
An Oracle DATE does not store times with more precision than a second. You cannot store millisecond precision data in a DATE column.
Your two options are to either truncate the string of the milliseconds before converting it into a DATE, i.e.
to_date( substr('23.12.2011 13:01:001', 1, 19), 'DD.MM.YYYY HH24:MI:SS' )
or to convert the string into a TIMESTAMP that does support millisecond precision
to_timestamp( '23.12.2011 13:01:001', 'DD.MM.YYYY HH24:MI:SSFF3' )
TO_DATE supports conversion to DATE datatype, which doesn't support milliseconds. If you want millisecond support in Oracle, you should look at TIMESTAMP datatype and TO_TIMESTAMP function.
Hope that helps.
For three digits millisecond:
TO_CHAR(LN_AUTOD_UWRG_DTTM,'MM/DD/YYYY HH24:MI:SS.FF3')
For six digits millisecond:
TO_CHAR(LN_AUTOD_UWRG_DTTM,'MM/DD/YYYY HH24:MI:SS.FF'),
You can try this format SS.FF for milliseconds:
to_timestamp(table_1.date_col,'DD-Mon-RR HH24:MI:SS.FF')
For more details:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions193.htm
You have to change date class to timestamp.
String s=df.format(c.getTime());
java.util.Date parsedUtilDate = df.parse(s);
java.sql.Timestamp timestamp = new java.sql.Timestamp(parsedUtilDate.getTime());

Oracle current_timestamp to seconds conversion

We are using Oracle database.
In our table timestamp is stored as seconds since 1970, how can I convert the time stamp obtained through current_timestamp() function to seconds
This would do it:
select round((cast(current_timestamp as date) - date '1970-01-01')*24*60*60) from dual
Though I wouldn't use current_timestamp if I was only interested in seconds, I would use SYSDATE:
select round((SYSDATE - date '1970-01-01')*24*60*60) from dual
Maybe not completely relevant. I had to resolve other way around problem (e.g. Oracle stores timestamp in V$RMAN_STATUS and V$RMAN_OUTPUT) and I had to convert that to date/timestamp. I was surprised, but the magic date is not 1970-01-01 there, but 1987-07-07. I looked at Oracle's history and the closest date I can think of is when they ported Oracle products to UNIX. Is this right?
Here's my SQL
SELECT /*+ rule */
to_char(min(stamp)/(24*60*60) + date '1987-07-07', 'DD-MON-YYYY HH24:MI:SS') start_tm
, to_char(to_char(max(stamp)/(24*60*60) + date '1987-07-07', 'DD-MON HH24:MI:SS')) end_tm
FROM V$RMAN_STATUS
START WITH (RECID, STAMP) =
(SELECT MAX(session_recid),MAX(session_stamp) FROM V$RMAN_OUTPUT)
CONNECT BY PRIOR RECID = parent_recid ;
I needed to send timestamp to GrayLog via GELF from Oracle DB. I tried different versions and solutions but only one worked correctly.
SQL:
SELECT REPLACE((CAST(dat AS DATE) - TO_DATE('19700101', 'YYYYMMDD')) * 86400 + MOD(EXTRACT(SECOND FROM dat), 1), ',', '.') AS millis
FROM (SELECT SYSTIMESTAMP AT TIME ZONE 'GMT' AS dat FROM dual)
The result for Systmiestamp
2018/12/18 19:47:29,080988 +02:00
will be
1545155249.080988

Resources