15

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

我正在 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 时间戳字符串?非常感谢!!

4

5 回答 5

18

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

唯一处理纪元秒的 Hive 函数似乎是它在服务器 timezonefrom_unixtime()中为您提供了一个时间戳字符串,我在我的例子中找到了它。/etc/sysconfig/clock"America/Montreal"

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

这一切似乎都很痛苦,尤其是必须将服务器 TZ 连接到 SQL 中。如果有from_unixtime_utc()功能或其他东西,生活会更轻松。


更新from_utc_timestamp()确实处理毫秒参数以及字符串,但随后转换错误。

当我尝试from_utc_timestamp(1389802875000, 'America/Los_Angeles')时,它给出了"2014-01-15 03:21:15"错误。
正确答案是"2014-01-15 08:21:15"您可以通过以下方式获得(对于蒙特利尔的服务器)from_utc_timestamp(to_utc_timestamp(from_unixtime(1389802875),'America/Montreal'), 'America/Los_Angeles')

于 2014-01-15T17:07:09.737 回答
8

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

#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)

于 2016-05-18T16:56:52.290 回答
3

像这样使用它:

to_utc_timestamp(from_unixtime(timestamp),"PDT")

于 2014-02-05T05:29:10.713 回答
1

此示例为您的配置单元代码中具有系统时区 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 的第二个参数。

于 2015-08-25T19:00:47.950 回答
-2

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

于 2013-08-17T12:21:26.903 回答