You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:15:26