Apache NiFi中Unix时间戳转实际日期失败问题排查
Apache NiFi Unix时间戳转日期错误排查与解决
核心问题
你的时间戳是秒级Unix时间戳,但NiFi的format函数、Parquet的timestamp-millis逻辑类型默认以毫秒为单位计算。直接将秒数当作毫秒值处理,会导致计算出的日期回到1970年附近(1671785608毫秒≈19.35天,对应1970/01/20)。
分步解决方法
1. 修正Schema类型定义
当前CSV Reader中starttime和endtime被定义为string类型,且未处理秒转毫秒的逻辑,导致后续转换失效。
- CSV Reader Schema 修改:将
starttime、endtime改为long类型,确保数字字符串能被正确解析为数值:
{ "type" : "record", "name" : "spark_schema", "fields" : [ { "name" : "excelReader", "type" : [ "null", "string" ], "default" : null }, { "name" : "time", "type" : [ "null", "long" ], "default" : null }, { "name" : "starttime", "type" : [ "null", "long" ], "default" : null }, { "name" : "endtime", "type" : [ "null", "long" ], "default" : null } ] }
- Parquet Writer Schema 修改:统一使用
timestamp-millis逻辑类型,同时确保输入值为毫秒级:
{ "type" : "record", "name" : "spark_schema", "fields" : [ { "name" : "excelReader", "type" : [ "null", "string" ], "default" : null }, { "name" : "time", "type" : [ "null", "long" ], "default" : null }, { "name" : "starttime", "type": { "type":"long", "logicalType":"timestamp-millis"}, "default" : null }, { "name" : "endtime", "type": { "type":"long", "logicalType":"timestamp-millis"}, "default" : null } ] }
2. 处理时间戳单位转换
在ConvertRecord之前添加UpdateRecord组件,将秒级时间戳乘以1000转为毫秒:
- 添加属性:
/starttime→${field.value:multiply(1000)} - 添加属性:
/endtime→${field.value:multiply(1000)} - 注:如果原始数据中
endtime末尾有.(如示例中的1671785608.),需先用ReplaceText组件去除:搜索值设为(.*)\.$,替换值设为$1,替换模式选Regex Replace。
3. 修正PartitionRecord中的format函数
如果不想调整前置流程,可直接在format函数中完成秒转毫秒的计算:
a_endtime_converted→format(/endtime:toNumber():multiply(1000), "yyyy/MM/dd/HH", "GMT")a_startime_converted→format(/starttime:toNumber():multiply(1000), "yyyy/MM/dd/HH", "GMT")a_time_converted→format(/time:multiply(1000), "yyyy/MM/dd/HH", "GMT")
内容的提问来源于stack exchange,提问作者Paul C.
相关产品推荐
相关产品推荐

