GSON - Формат дати


187

Я намагаюся мати власний формат дати у виведенні Gson, але .setDateFormat(DateFormat.FULL), здається, не працює, і це те ж саме .registerTypeAdapter(Date.class, new DateSerializer()).

Наче Gson не піклується про об’єкт "Date" і друкує його на своєму шляху.

Як я можу це змінити?

Дякую

Редагувати:

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

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

Я завжди користуюся java.util.Date; setDateFormat()не працює :(


Ви перевірили, що ви імпортуєте правильний клас дат у всіх місцях? Також корисним буде приклад коду.
ML

Що ви маєте на увазі під не працює? Що ви насправді бачите?
AlikElzin-kilaka

Відповіді:


306

Здається, що вам потрібно визначити формати як для частини, так і для дати та часу або використовувати форматне базування на основі рядків. Наприклад:

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

або за допомогою java.text.DateFormat

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

або робити це за допомогою серіалізаторів:

Я вважаю, що форматори не можуть створювати часові позначки, але ця пара серіалізаторів / десеріалізаторів, здається, працює

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 або вище, вам слід скористатись описаними вище серіалізаторами / десеріалізаторами:

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

Гаразд, це краще працює з вашим способом. Але як я можу відобразити часові позначки за допомогою цього?
Stéphane Piette

6
Я використовую Gson 2.2.4 і Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();працює.
Рамшаран

за допомогою Gson 2.2.2 та Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();працює
user2601995

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

Наданий формат мені здається кращим, оскільки він має точність до міліс.


1
@Abhi - Чому потрібне цитування "Z"?
tj-перерва

1
Я спробував без лапок і gson кинув виняток, що дата не піддається синтаксичному аналізу. Це працює на вас без лапок?
Абхі

7
Це НЕ правильне рішення .. Z означає часовий пояс, і він представляє часовий пояс UTC, якщо ви жорстко
кодуєте

5

Як вказував ML, тут працює JsonSerializer. Однак якщо ви форматуєте об'єкти бази даних, використовуйте java.sql.Date, щоб зареєструвати серіалізатор. Десеріалізатор не потрібен.

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

Цей звіт про помилку може бути пов’язаний: http://code.google.com/p/google-gson/isissue/detail?id=230 . Хоча я використовую версію 1.7.2.


4

Якщо ви ненавидите внутрішні класи, скориставшись перевагою функціонального інтерфейсу, ви можете написати менше коду на Java 8 з лямбда-виразом.

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

Здається, що нульову перевірку можна опустити (Gson робить це сам):Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsLong())).create();
gmk57

0

Це насправді не спрацює взагалі. У JSON відсутній тип дати. Я б рекомендував серіалізуватись до ISO8601 вперед і назад (для агностіки формату та JS compat). Вважайте, що ви повинні знати, які поля містять дати.


0

Ви можете вказати формат Gson gson = builder.setDateFormat("yyyy-MM-dd").create(); у цьому методі, а yyyy-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

Це помилка . В даний час вам або потрібно встановити « timeStyleа» або скористатися однією з альтернатив, описаних в інших відповідях.


0

Я на Gson 2.8.6 і виявив цю помилку сьогодні.

Мій підхід дозволяє всім нашим існуючим клієнтам (мобільний / веб / тощо) продовжувати функціонувати так, як вони були, але додає певну обробку для тих, хто використовує цілодобові формати, і дозволяє також мільйони для гарної міри.

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

Я зберігав серіалізацію так само, як усі клієнти розуміють стандартний формат дати json.

Зазвичай, я не думаю, що це корисна практика використання блоків спробу / лову, але це має бути досить рідкісним випадком.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.