如何使用Java中的AVRO序列化Date

Mig*_* L. 13 java serialization datetime 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用于序列化/反序列化的代码:

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并输出:

EXPECTED: 06/11/2012 05:43:29.188
ACTUAL: 06/11/2012 05:43:29.387
Run Code Online (Sandbox Code Playgroud)

它是否与已知错误有关,还是与我序列化对象的方式有关?

小智 18

Avro 1.8现在有一个日期"logicalType",它注释了int.例如:

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

引用规范:"日期逻辑类型注释Avro int,其中int存储unix时代,1970年1月1日(ISO日历)的天数."

  • @AlessandroDionisi 规范要求使用日期,因为此特定类型是自纪元以来的天数。还有另一种逻辑类型“timestamp-millis”,用于更常见的毫秒数,它是一个很长的类型。 (2认同)

ama*_*mas 7

我认为AVRO此时没有序列化日期.我要做的是将它包装在另一个类中并以long(date.gettime())存储,而avro人员添加此功能.并且您看到不同Date值的原因是每次您(和avro)创建Date对象时,它都会使用当前系统时间初始化Date.