How to serialize a Date using AVRO in Java

跟風遠走 提交于 2019-12-06 18:26:31

问题


I'm actually trying to serialize objects containing dates with Avro, and the deserialized date doesn't match the expected value (tested with avro 1.7.2 and 1.7.1). Here's the class I'm serializing :

import java.text.SimpleDateFormat;
import java.util.Date;

public class Dummy {
    private Date date;
    private SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");

    public Dummy() {
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Date getDate() {
        return date;
    }

    @Override
    public String toString() {
        return df.format(date);
    }
}

The code used to serialize / deserialize :

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;

import org.apache.avro.Schema;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.reflect.ReflectData;
import org.apache.avro.reflect.ReflectDatumReader;
import org.apache.avro.reflect.ReflectDatumWriter;

public class AvroSerialization {

    public static void main(String[] args) {
        Dummy expected = new Dummy();
        expected.setDate(new Date());
        System.out.println("EXPECTED: " + expected);
        Schema schema = ReflectData.get().getSchema(Dummy.class);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Encoder encoder = EncoderFactory.get().binaryEncoder(baos, null);
        DatumWriter<Dummy> writer = new ReflectDatumWriter<Dummy>(schema);
        try {
            writer.write(expected, encoder);
            encoder.flush();
            Decoder decoder = DecoderFactory.get().binaryDecoder(baos.toByteArray(), null);
            DatumReader<Dummy> reader = new ReflectDatumReader<Dummy>(schema);
            Dummy actual = reader.read(null, decoder);
            System.out.println("ACTUAL: " + actual);
        } catch (IOException e) {
            System.err.println("IOException: " + e.getMessage());
        }
    }
}

And the output :

EXPECTED: 06/11/2012 05:43:29.188
ACTUAL: 06/11/2012 05:43:29.387

Is it related to a known bug, or is it related to the way I'm serializing the object ?


回答1:


I think AVRO doesn't serialize date at this point. What I would do is to wrap it in another class and store at as a long (date.gettime()) while avro folks add this feature. And the reason that you see different Date values is that every time that you (and avro) create a Date object, it initializes the Date with the current System time.




回答2:


Avro 1.8 now has a date "logicalType", which annotates int. For example:

{"name": "date", "type": "int", "logicalType": "date"}

Quoting the spec: "A date logical type annotates an Avro int, where the int stores the number of days from the unix epoch, 1 January 1970 (ISO calendar)."



来源:https://stackoverflow.com/questions/13255589/how-to-serialize-a-date-using-avro-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!