Reputation: 7162
I thought this would be easy ...
In Hive/SparkSQL, how do I convert a unix timestamp [Note 1] into a timestamp
data type?
(Note 1: That is, number of seconds/milliseconds since Jan 1, 1970)
I thought from_unixtime()
would do that, but it gives back a string
instead of a timestamp. The following experiment illustrates the problem
Step 0: Preparation
select
from_unixtime(1508673584) as fut;
Result:
-----------------------
| fut |
| ------------------- |
| 2017-10-22 11:59:44 |
-----------------------
Step 1: Create a table with the result of from_unixtime()
create table test
select
from_unixtime(1508673584) as fut;
Step 2: Examine the datatype of the column fut
describe test;
Result:
----------------------------------
| col_name | data_type | comment |
| -------- | --------- | ------- |
| fut | string | <null> |
----------------------------------
I also tried this
select
from_utc_timestamp(1508618794*1000, 'EDT');
According to the manual (link here), this should work. Because it states that:
Coverts a timestamp* in UTC to a given timezone (as of Hive 0.8.0). * timestamp is a primitive type, including timestamp/date, tinyint/smallint/int/bigint, float/double and decimal. Fractional values are considered as seconds. Integer values are considered as milliseconds.. E.g from_utc_timestamp(2592000.0,'PST'), from_utc_timestamp(2592000000,'PST') and from_utc_timestamp(timestamp '1970-01-30 16:00:00','PST') all return the timestamp 1970-01-30 08:00:00
However, I got an error of
Error: org.apache.spark.sql.AnalysisException:
cannot resolve 'from_utc_timestamp((1508618794 * 1000), 'EDT')'
due to data type mismatch:
argument 1 requires timestamp type,
however, '(1508618794 * 1000)' is of int type.; line 2 pos 2;
'Project [unresolvedalias(from_utc_timestamp((1508618794 * 1000), EDT), None)]
+- OneRowRelation$
SQLState: null
ErrorCode: 0
Upvotes: 2
Views: 8379
Reputation: 75
create table test AS select cast(from_unixtime(1508673584) as timestamp) as fut;
Upvotes: 1
Reputation: 7162
(I am providing an answer myself here.)
The answer is to use cast()
. This works for both date
and timestamp
select
from_unixtime(1508673584) as fut,
cast(from_unixtime(1508673584) as date) as futAsDate,
cast(from_unixtime(1508673584) as timestamp) as futAsTimestamp;
Result:
------------------------------------------------------------
| fut | futAsDate | futAsTimestamp |
| ------------------- | ---------- | --------------------- |
| 2017-10-22 11:59:44 | 2017-10-22 | 2017-10-22 11:59:44.0 |
------------------------------------------------------------
Verification of data types
create table test2
select
from_unixtime(1508673584) as fut,
cast(from_unixtime(1508673584) as date) as futAsDate,
cast(from_unixtime(1508673584) as timestamp) as futAsTimestamp;
And then
describe test2;
Result:
----------------------------------------
| col_name | data_type | comment |
| -------------- | --------- | ------- |
| fut | string | <null> |
| futAsDate | date | <null> |
| futAsTimestamp | timestamp | <null> |
----------------------------------------
Upvotes: 2