web-dev-qa-db-ja.com

Java)でAVROを使用して日付をシリアル化する方法

私は実際にAvroで日付を含むオブジェクトをシリアル化しようとしていますが、逆シリアル化された日付が期待値と一致しません(avro 1.7.2および1.7.1でテスト済み)。これが私がシリアル化しているクラスです:

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

シリアル化/逆シリアル化に使用されるコード:

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());
        }
    }
}

そして出力:

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

それは既知のバグに関連していますか、それともオブジェクトをシリアル化する方法に関連していますか?

13
Miguel L.

AVROは現時点では日付をシリアル化していないと思います。私がすることは、それを別のクラスでラップし、長い(date.gettime())として保存し、avroの人々は この機能 を追加することです。また、異なるDate値が表示される理由は、(およびavroが)Dateオブジェクトを作成するたびに、現在のシステム時刻でDateが初期化されるためです。

7
amas

Avro 1.8には、intに注釈を付ける日付「logicalType」があります。例えば:

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

仕様の引用:「日付論理型はAvro intに注釈を付けます。ここで、intは1970年1月1日のUNIXエポック(ISOカレンダー)からの日数を格納します。」

20
teu