什么版本的 Hive 需要在小数秒内设置超过 6 位小数的时间戳?

问题描述

我需要什么版本的 Hive 才能使用这个:

https://cwiki.apache.org/confluence/display/Hive/CAST...FORMAT+with+SQL%3A2016+datetime+formats

它列出了一种将字符串转换为给定格式的时间戳的方法,但它似乎不起作用,并且与此功能相关的 Jira 故事似乎从未发布过。 https://issues.apache.org/jira/browse/HIVE-21575

有人知道吗?

解决方法

Jira HIVE-21575 是关于引入一种使用 SQL:2016 兼容格式而不是当前使用的 SimpleDateFormat 的方法,同时它应该提供一种简单的方法来精确转换非标准时间戳格式。 我发现在 4.0 版中发布的子 Jira HIVE-21868

如果您拥有 Hive

  1. 标准时间戳格式为“yyyy-MM-dd HH:mm:ss.SSSSSSSSS”(最高 9 位精度)。如果你有这种格式的字符串,你可以使用timestamp(str)cast(str as timestamp)转换成时间戳,虽然在大多数情况下你不需要显式转换,它会隐式完成,精度不会丢失,你可以将此类字符串插入时间戳列中,并与时间戳进行比较,无需转换。

  2. 对于具有纳秒的非标准格式的时间戳,您需要进行转换。 这里的问题是 date_format 方法不起作用,因为它需要标准格式的时间戳。 from_unixtime(unix_timestamp(str,format)) 不起作用,因为 unix_timestamp 函数返回的是秒,而不是纳秒,在此转换后,毫秒和纳秒将丢失。

非标准格式的解决方案是从字符串中提取毫秒或纳秒,使用 unix_timestamp(str,format) 以秒为单位应用转换,将结果与毫秒连接,然后使用 timestamp() 或强制转换转换为时间戳(这最后一步不是必须的)。

演示(Hive 2.3.6):

with your_data as (
select
'16AUG2001:23:46:32.123456789'  --non standard format
 as ts
) 

select ts as original_string,timestamp( --in most cases you can do without final timestamp() conversion
       concat(
              from_unixtime(unix_timestamp(split(ts,'\\.')[0],'ddMMMyyyy:HH:mm:ss')),--timestamp with seconds precision
              '.',split(ts,'\\.')[1] --digits after dot
             ) 
                ) as timestamp_converted
  from your_data;

结果:

original_string                 timestamp_converted
16AUG2001:23:46:32.123456789    2001-08-16 23:46:32.123456789

如您所见,它在纳秒级精度下运行良好。我使用最终时间戳(字符串)转换只是为了表明生成的字符串与时间戳兼容,您可以省略显式转换时间戳(字符串)。

  1. 如果您最初拥有以毫秒为单位的 bigint unix 时间戳并希望将其转换为 Hive 时间戳,请参阅此秘籍:https://stackoverflow.com/a/63672215/2700344

  2. 如果您有类似“2019-11-02T20:18:00.123Z”这样的字符串,请使用稍微不同的方法,请参阅:https://stackoverflow.com/a/58713989/2700344 如果可以使用 regexp_replace 将字符串轻松转换为标准格式,则此方法有效。