GSON - Định dạng ngày


187

Tôi đang cố gắng có định dạng ngày tùy chỉnh trong đầu ra Gson, nhưng .setDateFormat(DateFormat.FULL)dường như không hoạt động và nó cũng tương tự .registerTypeAdapter(Date.class, new DateSerializer()).

Giống như Gson không quan tâm đến đối tượng "Ngày" và in nó theo cách của nó.

Làm thế nào tôi có thể thay đổi điều đó?

Cảm ơn

BIÊN TẬP:

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

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

Tôi luôn luôn sử dụng java.util.Date; setDateFormat()không hoạt động :(


Bạn đã kiểm tra rằng bạn đang nhập đúng ngày-class ở tất cả các nơi chưa? Ngoài ra ví dụ mã sẽ hữu ích.
ML

Ý bạn là gì khi không làm việc? Bạn thực sự thấy gì?
AlikElzin-kilaka

Câu trả lời:


305

Có vẻ như bạn cần xác định định dạng cho cả phần ngày và giờ hoặc sử dụng định dạng dựa trên Chuỗi. Ví dụ:

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

hoặc sử dụng java.text.DateFormat

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

hoặc làm điều đó với serial serial:

Tôi tin rằng các trình định dạng không thể tạo ra dấu thời gian, nhưng cặp serializer / deserializer này dường như hoạt động

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

Nếu sử dụng Java 8 trở lên, bạn nên sử dụng các trình tuần tự hóa / giải tuần tự như trên:

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

Ok nó hoạt động tốt hơn với cách của bạn. Nhưng làm thế nào tôi có thể hiển thị dấu thời gian với điều này?
Stéphane Piette

6
Tôi đang sử dụng Gson 2.2.4 và Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();hoạt động.
Ramsharan

sử dụng Gson 2.2.2 và Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();hoạt động
user2601995

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

Định dạng trên có vẻ tốt hơn đối với tôi vì nó có độ chính xác lên đến hàng nghìn.


1
@ Abhi - Tại sao trích dẫn 'Z' là cần thiết?
tj-recess

1
Tôi đã thử mà không có dấu ngoặc kép và gson đã ném Ngoại lệ rằng ngày không thể phân tích cú pháp. Nó làm việc cho bạn mà không có dấu ngoặc kép?
Abhi

7
Đó không phải là giải pháp đúng .. Z có nghĩa là múi giờ và nó đại diện cho múi giờ UTC, nếu bạn mã hóa cứng như thế này, bạn sẽ mất thông tin đó
Billda

5

Như ML đã chỉ ra, JsonSerializer hoạt động ở đây. Tuy nhiên, nếu bạn đang định dạng các thực thể cơ sở dữ liệu, hãy sử dụng java.sql.Date để đăng ký tuần tự hóa. Deserializer là không cần thiết.

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

Báo cáo lỗi này có thể liên quan: http://code.google.com.vn/p/google-gson/issues/detail?id=230 . Tôi sử dụng phiên bản 1.7.2 mặc dù.


4

Trong trường hợp nếu bạn ghét các lớp bên trong, bằng cách tận dụng lợi thế của giao diện chức năng, bạn có thể viết ít mã hơn trong Java 8 bằng biểu thức lambda.

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

Dường như kiểm tra null có thể được bỏ qua (Gson tự thực hiện):Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsLong())).create();
gmk57

0

Điều này sẽ không thực sự làm việc cả. Không có loại ngày trong JSON. Tôi khuyên bạn nên tuần tự hóa tới ISO8601 qua lại (đối với định dạng bất khả tri và compat JS). Hãy xem xét rằng bạn phải biết trường nào chứa ngày.


0

Bạn có thể chỉ định định dạng của mình Gson gson = builder.setDateFormat("yyyy-MM-dd").create(); trong phương thức này thay vì yyyy-MM-ddbạn có thể sử dụng bất kỳ định dạng nào khác

 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

Đây là một lỗi . Hiện tại, bạn cũng phải đặt một timeStylehoặc sử dụng một trong những lựa chọn thay thế được mô tả trong các câu trả lời khác.


0

Tôi đang dùng Gson 2.8.6 và phát hiện ra lỗi này ngày hôm nay.

Cách tiếp cận của tôi cho phép tất cả các khách hàng hiện tại của chúng tôi (thiết bị di động / web / v.v.) tiếp tục hoạt động như cũ, nhưng thêm một số xử lý cho những người sử dụng định dạng 24h và cũng cho phép nhiều millis.

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ôi giữ serialization giống như tất cả các khách hàng hiểu định dạng ngày json tiêu chuẩn.

Thông thường, tôi không nghĩ rằng đó là cách tốt để sử dụng các khối thử / bắt, nhưng đây là trường hợp khá hiếm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.