首页 > 解决方案 > 如何通过在 Hive 中保留数据中的毫秒数将 UTC 转换为 CST 时间戳

问题描述

我有一个配置单元表,其中数据类型时间戳的数据采用 UTC 格式。我在此表顶部创建了一个视图,以转换UTCCST夏令时。这种转换工作正常。但是数据中缺少毫秒。

以下逻辑用于将 UTC 转换为 CST

FROM_UTC_TIMESTAMP(UNIX_TIMESTAMP(added_date, 'yyyy-MM-dd HH:mm:ss.SSS') * 1000, 'CST6CDT')

请帮助我转换UTCCST在时间戳中包含毫秒。

标签: hivetimestamphiveqlunix-timestampmilliseconds

解决方案


unix_timestamp() 函数忽略毫秒。它返回从 unix 纪元传递的秒数。毫秒丢失。例如:

 select FROM_UTC_TIMESTAMP(UNIX_TIMESTAMP('2020-01-21 15:15:35.125', 'yyyy-MM-dd HH:mm:ss.SSS') * 1000, 'CST6CDT');

返回:

2020-01-21 09:15:35

如果时间戳采用正确的格式 'yyyy-MM-dd HH:mm:ss.SSS'(在您的示例中,根据模板,它不需要转换),这可以正常工作:

with s as (select '2020-01-21 15:15:35.125' as added_date) 

select FROM_UTC_TIMESTAMP(s.added_date, 'CST6CDT')  from s;

结果:

2020-01-21 09:15:35.125

如果时间戳是需要转换的格式,解决方法是从原始时间戳中提取毫秒,并添加到将 unix_timestamp 乘以 1000 后得到的毫秒:

with s as (select '2020-01-21 15:15:35.125' as added_date) 

select FROM_UTC_TIMESTAMP(UNIX_TIMESTAMP(s.added_date, 'yyyy-MM-dd HH:mm:ss.SSS') * 1000+cast(split(added_date,'\\.')[1] as int), 'CST6CDT')  from s;

结果:

2020-01-21 09:15:35.125

另一种解决方法是用毫秒级联:

with s as (select '2020-01-21 15:15:35.125' as added_date) 

select concat_ws('.',cast(FROM_UTC_TIMESTAMP(UNIX_TIMESTAMP(s.added_date, 'yyyy-MM-dd HH:mm:ss.SSS') * 1000, 'CST6CDT') as string),split(added_date,'\\.')[1]) from s;

结果:

2020-01-21 09:15:35.125

推荐阅读