【问题标题】:Local Time Convert To UTC Time In Hive本地时间转换为 Hive 中的 UTC 时间
【发布时间】:2013-08-19 04:23:36
【问题描述】:

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

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

【问题讨论】:

    标签: timestamp hive utc


    【解决方案1】:

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

    【讨论】:

    • 我也试过了,但时间仍然不对...我什至看到一个帖子说我们应该将 1349049600000 乘以 1.0 (1349049600000*1.0),但也不起作用..仍然感谢您的帮助!
    • 你可以试试 to_utc_timestamp 吗?我相信它具有相同的语法。
    【解决方案2】:

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

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

    因此您可以通过to_utc_timestamp(from_unixtime(1389802875),'America/Montreal') 获取UTC 时间戳字符串,然后通过from_utc_timestamp() 转换为您的目标时区

    这一切似乎都很痛苦,尤其是必须将服务器 TZ 连接到 SQL 中。如果有 from_unixtime_utc() 函数之类的,生活会更轻松。


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

    当我尝试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')获得(对于蒙特利尔的服务器)

    【讨论】:

    【解决方案3】:

    像这样使用它:

    to_utc_timestamp(from_unixtime(timestamp),"PDT")

    【讨论】:

    • 这得到了赞成,但看起来应该是from_utc_timestamp(from_unixtime(timestamp),"PDT")
    • @ChrisA。用户想要将时间转换为 utc 时区,这就是这个函数的原因。
    【解决方案4】:

    此示例提供了一个解决方案,以解决在您的 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 的第二个参数。

    【讨论】:

      【解决方案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)

      【讨论】:

        猜你喜欢
        • 2018-07-27
        • 1970-01-01
        • 2014-07-18
        • 2021-02-04
        • 2010-09-15
        • 2016-07-29
        • 2011-05-01
        • 2019-04-30
        相关资源
        最近更新 更多