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

또는 serializer로 수행하십시오.

포맷터에서 타임 스탬프를 생성 할 수는 없지만이 시리얼 라이저 / 디시리얼라이저 쌍이 작동하는 것 같습니다

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 이상을 사용하는 경우 위의 serializer / deserializer를 다음과 같이 사용해야합니다.

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();있습니다.
Ramsharan

Gson 2.2.2 사용 및 Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();작동
user2601995 0시 44 분에

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

위의 형식은 최대 밀리미터의 정밀도를 갖기 때문에 나에게 더 좋습니다.


1
@Abhi-왜 'Z'를 인용해야합니까?
tj-recess

1
나는 따옴표없이 시도했고 gson은 날짜를 구문 분석 할 수 없다는 예외를 던졌습니다. 따옴표없이 당신을 위해 작동합니까?
Abhi

7
이것은 올바른 해결책이 아닙니다.. Z는 시간대를 의미하며 UTC 시간대를 나타냅니다. 이와 같이 하드 코딩하면 해당 정보를 잃게됩니다
Billda

5

ML이 지적했듯이 JsonSerializer는 여기서 작동합니다. 그러나 데이터베이스 엔티티를 형식화하는 경우 java.sql.Date를 사용하여 직렬 변환기를 등록하십시오. 디시리얼라이저는 필요하지 않습니다.

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

이 버그 보고서는 http://code.google.com/p/google-gson/issues/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();

null 검사는 생략 할 수있는 것 같습니다 (Gson 자체가 Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsLong())).create();
수행함

0

이것은 실제로 작동하지 않습니다. JSON에는 날짜 유형이 없습니다. 형식에 구애받지 않고 JS compat을 위해 ISO8601로 직렬화하는 것이 좋습니다. 날짜를 포함하는 필드를 알아야합니다.


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을 사용하고 있으며 오늘이 버그를 발견했습니다.

내 접근 방식은 기존의 모든 클라이언트 (모바일 / 웹 / 등)가 그대로 작동하도록하지만 24 시간 형식을 사용하는 사람들을 위해 처리를 추가하고 밀리미터도 허용합니다.

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 날짜 형식을 이해하는 것처럼 직렬화를 유지했습니다.

일반적으로 try / catch 블록을 사용하는 것이 좋지 않다고 생각하지만 이것은 매우 드문 경우입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.