GSON - Tarih biçimi


187

Gson çıktısında özel bir tarih biçimine sahip olmaya çalışıyorum, ancak .setDateFormat(DateFormat.FULL)işe yaramıyor gibi görünüyor .registerTypeAdapter(Date.class, new DateSerializer()).

Gson, "Date" nesnesini umursamıyor ve onun yolunu yazdırmıyor gibi.

Bunu nasıl değiştirebilirim?

Teşekkürler

DÜZENLE:

@Entity
public class AdviceSheet {
  public Date lastModif;
[...]
}

public void method {
   Gson gson = new GsonBuilder().setDateFormat(DateFormat.LONG).create();
   System.out.println(gson.toJson(adviceSheet);
}

Her zaman kullanıyorum java.util.Date; setDateFormat()çalışmıyor :(


Her yere doğru Tarih sınıfı aktardığınızı kontrol ettiniz mi? Ayrıca kod örneği yardımcı olacaktır.
ML

Ne demek çalışmıyor? Aslında ne görüyorsun?
AlikElzin-kilaka

Yanıtlar:


306

Hem tarih hem de saat bölümü için biçimler tanımlamanız veya Dize tabanlı biçimlendirme kullanmanız gerektiği anlaşılıyor. Örneğin:

Gson gson = new GsonBuilder()
   .setDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz").create();

veya java.text.DateFormat kullanarak

Gson gson = new GsonBuilder()
   .setDateFormat(DateFormat.FULL, DateFormat.FULL).create();

veya serileştiricilerle yapın:

Biçimlendiricilerin zaman damgaları üretemediğine inanıyorum, ancak bu seri / deserializer çifti çalışıyor gibi görünüyor

JsonSerializer<Date> ser = new JsonSerializer<Date>() {
  @Override
  public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext 
             context) {
    return src == null ? null : new JsonPrimitive(src.getTime());
  }
};

JsonDeserializer<Date> deser = new JsonDeserializer<Date>() {
  @Override
  public Date deserialize(JsonElement json, Type typeOfT,
       JsonDeserializationContext context) throws JsonParseException {
    return json == null ? null : new Date(json.getAsLong());
  }
};

Gson gson = new GsonBuilder()
   .registerTypeAdapter(Date.class, ser)
   .registerTypeAdapter(Date.class, deser).create();

Java 8 veya üstünü kullanıyorsanız yukarıdaki diziselleştiricileri / serileştiricileri aşağıdaki gibi kullanmalısınız:

JsonSerializer<Date> ser = (src, typeOfSrc, context) -> src == null ? null
            : new JsonPrimitive(src.getTime());

JsonDeserializer<Date> deser = (jSon, typeOfT, context) -> jSon == null ? null : new Date(jSon.getAsLong());

Tamam, yolunuzla daha iyi çalışıyor. Ancak bununla zaman damgalarını nasıl görüntüleyebilirim?
Stéphane Piette

6
Gson 2.2.4 kullanıyorum ve Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();çalışıyor.
Ramsharan

2.2.2 ve Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();işleri kullanan kullanıcı
user2601995

66
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create();

Yukarıdaki format benim için daha iyi görünüyor çünkü milis'e kadar hassas.


1
@Abhi - 'Z' ile alıntı yapmak neden gerekli?
tj-recess

1
Tırnak işaretleri olmadan denedim ve gson, tarihin ayrıştırılabilir olmadığı istisnasını attı. Tırnak işaretleri olmadan sizin için çalışıyor mu?
Abhi

7
Bu doğru bir çözüm DEĞİLDİR .. Z saat dilimi anlamına gelir ve UTC saat dilimini temsil eder, eğer böyle
kodlarsanız

5

ML'nin işaret ettiği gibi, JsonSerializer burada çalışır. Ancak, veritabanı varlıklarını biçimlendiriyorsanız, serileştiriciyi kaydetmek için java.sql.Date kullanın. Deserializer gerekli değildir.

Gson gson = new GsonBuilder()
   .registerTypeAdapter(java.sql.Date.class, ser).create();

Bu hata raporu ilgili olabilir: http://code.google.com/p/google-gson/issues/detail?id=230 . 1.7.2 sürümünü kullanıyorum.


4

İç sınıflardan nefret ederseniz, fonksiyonel arayüzden yararlanarak, lambda ifadesiyle Java 8'de daha az kod yazabilirsiniz .

JsonDeserializer<Date> dateJsonDeserializer = 
     (json, typeOfT, context) -> json == null ? null : new Date(json.getAsLong());
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class,dateJsonDeserializer).create();

Görünüşe göre null kontrol atlanabilir (Gson kendisi yapar):Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsLong())).create();
gmk57

0

Bu gerçekten işe yaramayacak. JSON'da tarih türü yok. ISO8601'e ileri geri serileştirmenizi tavsiye ederim (format agnostics ve JS uyumlu). Hangi alanların tarih içerdiğini bilmeniz gerektiğini düşünün.


0

Başka bir format kullanmak Gson gson = builder.setDateFormat("yyyy-MM-dd").create(); yerine bu yöntemde format belirtebilirsinizyyyy-MM-dd

 GsonBuilder builder = new GsonBuilder();
                        builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
                            public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                                return new Date(json.getAsJsonPrimitive().getAsLong());
                            }
                        });

                        Gson gson = builder.setDateFormat("yyyy-MM-dd").create();

0

Bu bir hatadır . Şu anda ya da bir tane ayarlamanız timeStyleya da diğer cevaplarda açıklanan alternatiflerden birini kullanmanız gerekiyor.


0

Gson 2.8.6 kullanıyorum ve bugün bu hatayı keşfettim.

Yaklaşımım, mevcut tüm müşterilerimizin (mobil / web / vb.) Olduğu gibi çalışmaya devam etmesine izin verir, ancak 24 saat formatlarını kullananlar için biraz işlem ekler ve iyi ölçü için milislere de izin verir.

Gson rawGson = new Gson();
SimpleDateFormat fmt = new SimpleDateFormat("MMM d, yyyy HH:mm:ss")
private class DateDeserializer implements JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        try {
            return new rawGson.fromJson(json, Date.class);
        } catch (JsonSyntaxException e) {}
        String timeString = json.getAsString();
        log.warning("Standard date deserialization didn't work:" + timeString);
        try {
            return fmt.parse(timeString);
        } catch (ParseException e) {}
        log.warning("Parsing as json 24 didn't work:" + timeString);
        return new Date(json.getAsLong());
    }
}

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Date.class, new DateDeserializer())
    .create();

Tüm istemcilerin standart json tarih biçimini anlamasıyla aynı seriyi tuttum.

Normalde, try / catch bloklarını kullanmanın iyi bir uygulama olduğunu düşünmüyorum, ancak bu oldukça nadir bir durum olmalı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.