如何使用Apache Camel或Groovy转换Kafka Avro的int类型日期(logicalType:date)
Avro int日期格式(距1970-01-01天数)转换方案
针对Avro中用int存储、标注logicalType":"date"的日期类型(值为距1970-01-01的天数,支持正负),下面给出Apache Camel和Groovy的转换实现:
一、Apache Camel 实现
1. 把Avro int日期转成标准日期
用Camel Processor直接处理,利用Java 8+的LocalDate内置方法,刚好匹配这种epoch天数的转换逻辑:
from("direct:parseAvroDate") .process(exchange -> { Integer avroDayCount = exchange.getIn().getBody(Integer.class); if (avroDayCount != null) { // 直接通过epoch天数生成LocalDate LocalDate birthDate = LocalDate.ofEpochDay(avroDayCount); // 转成ISO格式字符串输出,也可以保留LocalDate对象 exchange.getIn().setBody(birthDate.toString()); } else { exchange.getIn().setBody(null); } });
2. 把标准日期转成Avro int格式
如果需要反向转换,将日期转为对应的天数:
from("direct:convertToAvroDate") .process(exchange -> { Object input = exchange.getIn().getBody(); LocalDate targetDate = null; if (input instanceof LocalDate) { targetDate = (LocalDate) input; } else if (input instanceof String) { targetDate = LocalDate.parse((String) input); } if (targetDate != null) { long epochDay = targetDate.toEpochDay(); // 检查是否在Avro int的32位范围里,避免溢出 if (epochDay >= Integer.MIN_VALUE && epochDay <= Integer.MAX_VALUE) { exchange.getIn().setBody((int) epochDay); } else { throw new IllegalArgumentException("该日期超出Avro int类型的存储范围"); } } else { exchange.getIn().setBody(null); } });
二、Groovy脚本实现
Groovy兼容Java的日期API,语法更简洁,适合快速脚本转换:
1. 解析Avro int为日期
// 示例输入:Avro存储的天数 def avroDayCount = -8364 if (avroDayCount != null) { def birthDate = LocalDate.ofEpochDay(avroDayCount) println "转换后日期: ${birthDate}" // 输出 1947-05-15 } else { println "日期值为null" }
2. 转换日期为Avro int格式
// 示例输入:ISO格式字符串日期 def targetDate = LocalDate.parse("1996-08-15") def avroDayCount = targetDate.toEpochDay() as Integer if (avroDayCount != null) { println "Avro格式的int日期: ${avroDayCount}" // 输出 9663 } else { println "该日期超出Avro int的存储范围" }
内容的提问来源于stack exchange,提问作者DummyGuy
相关产品推荐
相关产品推荐

