2012-11-06 53 views
8

我實際上是想用Avro序列化包含日期的對象,並且反序列化的日期與期望值不匹配(用avro 1.7.2和1.7.1測試)。下面是我序列化類:如何在Java中使用AVRO序列化日期

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 

這是否與一個已知的錯誤,或它與我序列化對象的方式有關嗎?

+1

我知道我沒有回答你的問題,但我*不會*使用靜態的SimpleDateFormat。它不是一個線程安全的類,因此會在線程環境中給出不可靠的結果 –

+0

感謝您的評論,這實際上不是一個生產代碼,而只是我開發的一個測試類,以揭露我的問題。無論如何,你是對的,所以我刪除了靜態修飾符;) –

回答

6

我認爲AVRO在這一點上不會序列化日期。 我會做的是把它包裝在另一個類中,並存儲在一個long(date.gettime()),而avro夥計 添加this feature。 而您看到不同日期值的原因是,您(和avro)每次創建Date對象時,都會使用當前系統時間初始化Date。

+0

謝謝阿馬斯,它看起來像日期實際上不支持您的答案中所述,並且日期實際上是用當前系統時間初始化。 –

7

Avro 1.8現在有一個日期「logicalType」,它註釋int。例如:

{ 「名稱」: 「日期」, 「類型」: 「INT」, 「logicalType」: 「日期」}

引用規範:「A日期邏輯類型註釋的阿夫羅INT,那裏int存儲1970年1月1日unix時代(ISO日曆)的天數。「

相關問題