本地时间转换为Hive中的UTC时间

时间:2013-08-16 17:14:46

标签: timestamp hive utc

我在互联网上搜索了很多但却找不到答案。这是我的问题:

我正在Hive中写一些查询。我有一个UTC时间戳,并希望将其更改为UTC时间,例如,给定时间戳1349049600,我想将其转换为UTC时间,即2012-10-01 00:00:00。但是,如果我在Hive中使用内置函数from_unixtime(1349049600),我将获得本地PDT时间2012-09-30 17:00:00。

我意识到有一个名为from_utc_timestamp(timestamp, string timezone)的内置函数。然后我尝试了from_utc_timestamp(1349049600, "GMT"),输出是1970-01-16 06:44:09.6,这是完全错误的。

我不想永久更改Hive的时区,因为还有其他用户。那么我有什么方法可以获得从1349049600到“2012-10-01 00:00:00”的UTC时间戳字符串?非常感谢!!

5 个答案:

答案 0 :(得分:14)

据我所知,from_utc_timestamp()需要一个日期字符串参数,如"2014-01-15 11:21:15",而不是unix seconds-since-epoch值。这可能就是为什么当你传递一个整数时它会给出奇怪的结果?

处理纪元秒的唯一Hive函数似乎是from_unixtime(),它在服务器时区中提供了一个时间戳字符串,我在/etc/sysconfig/clock中找到了 - {{ 1}}在我的情况下。

因此,您可以通过"America/Montreal"获取UTC时间戳字符串,然后使用to_utc_timestamp(from_unixtime(1389802875),'America/Montreal')

转换为目标时区

这一切似乎非常痛苦,尤其是必须将服务器TZ连接到SQL中。如果有from_utc_timestamp()函数或其他东西,生活会更容易。


更新from_unixtime_utc()会处理 milli 秒参数以及字符串,但会导致转换错误。

当我尝试from_utc_timestamp()时,它会给出from_utc_timestamp(1389802875000, 'America/Los_Angeles')这是错误的 正确的答案是"2014-01-15 03:21:15",您可以通过"2014-01-15 08:21:15"

获取(蒙特利尔的服务器)

答案 1 :(得分:5)

嘿,我只是想在这里添加一点,我建议尝试“自动化”系统时区。所以不是静态

#STATIC TZ deceleration     
to_utc_timestamp(from_unixtime(1389802875),'America/Montreal')

试一试

#DYNAMIC TZ
select to_utc_timestamp(from_unixtime(1389802875), from_unixtime(unix_timestamp(), "z"));

这只是使用字符串输出格式“from_unixtime”来返回时区字符串(小写z)

答案 2 :(得分:2)

像这样使用:

to_utc_timestamp(from_unixtime(timestamp),"PDT")

答案 3 :(得分:1)

此示例提供了在hive代码中具有系统时区TZ的硬连线值的问题的解决方案。它是在Centos环境中使用hive 0.10.0运行的,使用OpenJDK java版本1.6。因为它涉及时间操作,所以精确的软件修订可能很重要。目前该系统在EDT运行。表tblFiniteZahl就像一个DUAL,但有大约一百万行,你猜对了,有限数。但是你可以用至少1行替换任何表。诀窍是在本地时区格式化时间,但使用z格式捕获时区,然后在运行时提取该值以传递给to_utc_timestamp函数。

select D1,
       D1E,
       D1L,
       D1LT,
       D1LZ,
       to_utc_timestamp(D1LT, D1LZ) as D1UTC
from (
select D1,
       D1E,
       D1L,
       regexp_extract(D1L, '^([^ ]+[ ][^ ]+)[ ](.+)$', 1) as D1LT,
       regexp_extract(D1L, '^([^ ]+[ ][^ ]+)[ ](.+)$', 2) as D1LZ
from (
select D1,
       D1E,
       from_unixtime(D1E, 'yyyy-MM-dd HH:mm:ss z') as D1L
from (
select D1,
       unix_timestamp(D1,'yyyy-MM-dd HH:mm:ss Z') as D1E
from (
select '2015-08-24 01:15:23 UTC' as D1
from tblFiniteZahl
limit 1
      ) T1
      ) T2
      ) T3
      ) T4
;

结果是

D1 = 2015-08-24 01:15:23 UTC
DT3 = 1440378923
D1L = 2015-08-23 21:15:23 EDT
D1LT = 2015-08-23 21:15:23
D1LZ = EDT
D1UTC = 2015-08-23 21:15:23

这表明to_utc_timestamp确实采用了EDT的第二个参数。

答案 4 :(得分:-2)

我去了currentmillis.com并粘贴了1349049600而没有意识到它实际上是秒。确实它在日期中返回1970-01-16,这意味着你建议的函数:from_utc_timestamp实际上需要毫秒作为第一个参数?也许您可以使用from_utc_timestamp(1349049600000, "GMT")再试一次?