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()ไม่ทำงาน :(


คุณได้ตรวจสอบว่าคุณกำลังนำเข้า Date-class ที่ถูกต้องในทุกสถานที่หรือไม่ ตัวอย่างรหัสก็จะมีประโยชน์เช่นกัน
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();

หรือทำมันด้วย serializers:

ฉันเชื่อว่าตัวจัดรูปแบบไม่สามารถสร้างการประทับเวลาได้ แต่ serializer / deserializer-pair ดูเหมือนว่าจะทำงานได้

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 ขึ้นไปคุณควรใช้ serializers / deserializers ด้านบนดังนี้:

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

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 หากคุณ hardcode เช่นนี้คุณจะสูญเสียข้อมูลนั้น
Billda

5

ในฐานะที่เป็น ML ชี้ให้เห็น JsonSerializer ทำงานที่นี่ อย่างไรก็ตามหากคุณกำลังจัดรูปแบบเอนทิตีฐานข้อมูลให้ใช้ java.sql.Date เพื่อลงทะเบียนซีเรียลไลเซอร์ของคุณ ไม่จำเป็นต้องใช้ Deserializer

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

ดูเหมือนว่าการตรวจสอบโมฆะสามารถละเว้นได้ (Gson ทำเอง):Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsLong())).create();
gmk57

0

มันไม่ได้ผลเลย ไม่มีประเภทวันที่ใน JSON ฉันอยากจะแนะนำให้อนุกรมเป็น ISO8601 ไปมา (สำหรับรูปแบบ agnostics และ 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 และค้นพบข้อบกพร่องนี้แล้ววันนี้

วิธีการของฉันทำให้ลูกค้าที่มีอยู่ของเรา (มือถือ / เว็บ / ฯลฯ ) ทำงานต่อไปเหมือนเดิม แต่เพิ่มการจัดการบางอย่างสำหรับผู้ที่ใช้รูปแบบ 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 มาตรฐาน

โดยปกติฉันไม่คิดว่ามันเป็นวิธีปฏิบัติที่ดีในการใช้บล็อกลอง / จับ แต่นี่อาจเป็นกรณีที่ค่อนข้างหายาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.