问题描述
我需要什么版本的 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
-
标准时间戳格式为“yyyy-MM-dd HH:mm:ss.SSSSSSSSS”(最高 9 位精度)。如果你有这种格式的字符串,你可以使用
timestamp(str)
或cast(str as timestamp)
转换成时间戳,虽然在大多数情况下你不需要显式转换,它会隐式完成,精度不会丢失,你可以将此类字符串插入时间戳列中,并与时间戳进行比较,无需转换。 -
对于具有纳秒的非标准格式的时间戳,您需要进行转换。 这里的问题是
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
如您所见,它在纳秒级精度下运行良好。我使用最终时间戳(字符串)转换只是为了表明生成的字符串与时间戳兼容,您可以省略显式转换时间戳(字符串)。
-
如果您最初拥有以毫秒为单位的 bigint unix 时间戳并希望将其转换为 Hive 时间戳,请参阅此秘籍:https://stackoverflow.com/a/63672215/2700344
-
如果您有类似“2019-11-02T20:18:00.123Z”这样的字符串,请使用稍微不同的方法,请参阅:https://stackoverflow.com/a/58713989/2700344 如果可以使用 regexp_replace 将字符串轻松转换为标准格式,则此方法有效。