具有Java 8的Avro日期为逻辑类型

inj*_*cto 15 java avro java-8

最新的Avro编译器(1.8.2)使用基于Joda-Time的实现为日期逻辑类型生成java源.如何配置Avro编译器以生成使用Java 8日期时间API的源?

Auk*_*uke 13

目前(avro 1.8.2)这是不可能的.它是硬编码生成Joda日期/时间类.

当前master分支已切换到Java 8,并且存在一个开放问题(使用Pull Request)以添加生成java.time.*类型类的功能.

我不知道任何类型的发布时间表,master不幸的是当前的任何内容.如果您喜欢冒险,可以应用补丁1.8.2,因为理论上它应该都是兼容的.序列化/反序列化时的基础类型仍然是整数和长整数.


hol*_*ava 6

您需要创建自己的Conversion,以支持java-8 date-time api,以下为的转换java.time.LocalDate

class Java8LocalDateConversion extends Conversion<LocalDate> {
    @Override
    public Class<LocalDate> getConvertedType() {
        return LocalDate.class;
    }

    @Override
    public String getLogicalTypeName() {
        //      v--- reuse the logical type `date`
        return "date";
    }

    @Override
    // convert LocalDate to Integer
    public Integer toInt(LocalDate value, Schema schema, LogicalType type) {
        return (int) value.toEpochDay();
    }

    @Override
    // parse LocalDate from Integer
    public LocalDate fromInt(Integer value, Schema schema, LogicalType type) {
        return LocalDate.ofEpochDay(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

逻辑类型可以在avro中重用,因此您可以使用现有的date逻辑类型,例如:

Schema schema = LogicalTypes.date().addToSchema(Schema.create(Type.INT));
Run Code Online (Sandbox Code Playgroud)

对于序列化和反序列化,您应该设置GenericData,以找到自己的转换,例如:

//serializing
DatumWriter<T> out = new SpecificDatumWriter<>(schema, data());

// deserializing
DatumReader<T> in = new SpecificDatumReader<>(schema, schema, data());

private SpecificData data() {
    SpecificData it = new SpecificData();
    it.addLogicalTypeConversion(new Java8LocalDateConversion());
    return it;
}
Run Code Online (Sandbox Code Playgroud)

如果不想GenericData每次都配置,则可以改用全局GenericData,例如:

//      register the conversion globally ---v
SpecificData.get().addLogicalTypeConversion(new Java8LocalDateConversion());
Run Code Online (Sandbox Code Playgroud)