以毫秒为单位的 Hive FROM_UNIXTIME()

Hive FROM_UNIXTIME() with milliseconds

我已经看到足够多的帖子,其中我们除以 1000 或强制转换以从毫秒纪元时间转换为时间戳。我想知道我们如何在时间戳中保留毫秒部分。

1440478800123 最后3个字节是毫秒。我如何将其转换为 YYYYMMDDHHMMSS.sss

我还需要在转换后的时间戳中捕获毫秒部分

谢谢

在 java

中创建一个配置单元 udf
package com.kishore.hiveudf;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.udf.UDFType;

@UDFType(stateful = true)
public class TimestampToDateUDF extends UDF {
    String dateFormatted;
    public String evaluate(long timestamp) {
        Date date = new Date(timestamp);
        DateFormat formatter = new SimpleDateFormat("YYYYMMDDHHmmss:SSS");
        dateFormatted = formatter.format(date);
        return dateFormatted;
    }
}

导出为 TimestampToDateUDF.jar

hive> ADD JAR /home/kishore/TimestampToDate.jar; 
hive> create TEMPORARY FUNCTION toDate AS 'com.kishore.hiveudf.TimestampToDateUDF' ;

输出

select * from tableA;                                                           
OK
1440753288123
Time taken: 0.071 seconds, Fetched: 1 row(s)
hive> select toDate(timestamp) from tableA;
OK
201508240144448:123
Time taken: 0.08 seconds, Fetched: 1 row(s)
select cast(epoch_ms as timestamp)

实际上有效,因为在转换为时间戳时(与使用 from_unixtime() 相反),Hive 似乎假定 int 或 bigint 是毫秒。浮点类型被视为秒。据我所知,这是没有记录的,可能是一个错误。我想要一个包含时区的字符串(这可能很重要 - 特别是如果服务器更改为 summer/daylight 节省时间),并且想要明确转换以防转换功能发生变化。所以这给出了一个 ISO 8601 日期(根据需要调整格式字符串以获得另一种格式)

select from_unixtime(
   floor(  epoch_ms / 1000   )
 , printf( 'yyyy-MM-dd HH:mm:ss.%03dZ',  epoch_ms % 1000  )
 )