假设您想要一个 Hive 查询,这就是我如何将 Hive 时间戳列(使用当前系统时区)转换为 Impala 时间戳(使用与 GMT 相同的 UTC,但不推荐使用 GMT) .
CREATE TEMPORARY MACRO to_impala_timestamp(ts TIMESTAMP)
CAST(FROM_UNIXTIME(UNIX_TIMESTAMP(ts) +CAST(CAST(PRINTF('%tz', ts) AS FLOAT)*36.0 AS INT)) AS TIMESTAMP)
;
--## WARNING - do not use MACROs if your Hive version is below V1.3 (Apache, Horton)
--## or below V1.1-CDH5.7.3, V1.1-CDH5.8.3, V1.1-CDH5.9.0 (Cloudera)
--## cf. "HIVE-11432 Hive macro give same result for different arguments"
PRINTF('%tz', ts) 将提取时区,动态处理夏令时 -- 假设您正在处理的时间戳与 系统时区相关 由您的 Hadoop 集群使用。如果是不同的 TZ,那么您必须相应地调整宏。
您可以使用以下查询对其进行测试:
CREATE TABLE test_tz
STORED AS Parquet
AS
SELECT CAST(ts AS STRING) AS initial_ts_as_string
, printf('%1$tz %1$tZ', ts) AS tzone_offset_and_code
, ts AS ts_for_hive
, to_impala_timestamp(ts) AS ts_for_impala
FROM ...
我们的集群使用中欧时间,这就是结果在 Hive 中的显示方式...
+--------------------------+--------------------+-----------------------------+-------------------------+
| initial_ts_as_string | tz_offset_and_code | ts_for_hive | ts_for_impala |
+--------------------------+--------------------+-----------------------------+-------------------------+
| 2015-09-13 11:32:30.627 | +0200 CEST | 2015-09-13 11:32:30.627 | 2015-09-13 13:32:30.0 |
| 2015-12-10 12:27:01.282 | +0100 CET | 2015-12-10 12:27:01.282 | 2015-12-10 13:27:01.0 |
| 2016-05-17 15:49:06.386 | +0200 CEST | 2016-05-17 15:49:06.386 | 2016-05-17 17:49:06.0 |
...然后在 Impala 中...
+-------------------------+--------------------+-------------------------------+---------------------+
| initial_ts_as_string | tz_offset_and_code | ts_for_hive | ts_for_impala |
+-------------------------+--------------------+-------------------------------+---------------------+
| 2015-09-13 11:32:30.627 | +0200 CEST | 2015-09-13 09:32:30.627000000 | 2015-09-13 11:32:30 |
| 2015-12-10 12:27:01.282 | +0100 CET | 2015-12-10 11:27:01.282000000 | 2015-12-10 12:27:01 |
| 2016-05-17 15:49:06.386 | +0200 CEST | 2016-05-17 13:49:06.386000000 | 2016-05-17 15:49:06 |
请注意,运行转换时会丢失毫秒;他们可以通过一个额外的技巧来恢复,但通常这超出了重点。
旁注:要将时间戳(或日期或浮点数或其他)格式化为字符串,好的旧 Java
PRINTF() 函数比使用默认格式加上
REGEXP_***() 函数更实用......