Avro with Java 8 dates as logical type

You need to create your own Conversions to support java-8 date-time api, below is a conversion for 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);
    }
}

The logical types can be reused in avro, so you can using the existing date logical type, for example:

Schema schema = LogicalTypes.date().addToSchema(Schema.create(Type.INT));

For the serializing & deserializing you should set the GenericData which will find your own conversion, for example:

//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;
}

If you don't want to configure the GenericData every time, you can use the global GenericData instead, for example:

//      register the conversion globally ---v
SpecificData.get().addLogicalTypeConversion(new Java8LocalDateConversion());

  • use Avro version >= 1.9.0 < 1.10.0
  • add <dateTimeLogicalTypeImplementation>jsr310</dateTimeLogicalTypeImplementation> into configuration section.
  • use Avro version >= 1.10.0
  • java8/jsr310 native date/time classes used by default

Currently (avro 1.8.2) this is not possible. It's hardcoded to generate Joda date/time classes.

The current master branch has switched to Java 8 and there is an open issue (with Pull Request) to add the ability to generate classes with java.time.* types.

I have no idea on any kind of release schedule for whatever is currently in master unfortunately. If you feel adventurous you can apply the patch to 1.8.2, since in theory it should all be compatible. The underlying base types when serializing / deserializing are still integers and longs.

Tags:

Java

Avro

Java 8