2012-11-06 10 views
8

Próbuję serializować obiekty zawierające daty z Avro, a deserializowana data nie pasuje do oczekiwanej wartości (testowane z Avro 1.7.2 i 1.7.1). Oto klasa ja szeregowania:Jak serializować datę za pomocą AVRO w Javie

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

Kod używany do serializacji/deserializacji:

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

a wyjście:

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

Wiąże się to znany błąd, lub czy jest to związane ze sposobem serializacji obiektu?

+1

Wiem, że nie odpowiadam na twoje pytanie, ale * nie użyłbym * statycznego SimpleDateFormat. Nie jest to klasa bezpieczna dla wątków, a zatem da ci niewiarygodne wyniki w środowisku z gwintem. –

+0

Dziękuję za komentarz, to w rzeczywistości nie jest kod produkcyjny, ale tylko klasa testowa, którą opracowałem, aby odsłonić mój problem. W każdym razie masz rację, więc usunąłem modyfikator statyczny;) –

Odpowiedz

6

Uważam, że AVRO nie szereguje daty na tym etapie. Co mogę zrobić, to owinąć go w inną klasę i przechowywać jako długi (date.gettime()), podczas gdy avro ludzie dodać this feature. Powodem, dla którego widzisz różne wartości daty jest to, że za każdym razem, gdy tworzysz (i avro) obiekt , inicjalizuje on datę z bieżącym czasem systemowym.

+0

Dziękuję amas, wygląda na to, że Data nie jest faktycznie obsługiwana, jak podano w Twojej odpowiedzi, i że Data jest faktycznie inicjalizowana z bieżącym czasem systemowym. –

7

Avro 1.8 ma teraz datę "logicalType", która przypisuje int. Np

{ "Nazwa": "Data", "typu": "int", "logicalType": "Data"}

Cytowanie spec „a termin typ logiczny annotates int Avro, gdzie int przechowuje liczbę dni z epoki unix, 1 stycznia 1970 (kalendarz ISO). "

Powiązane problemy