2013-03-22 9 views
28

मेरा सर्वर जेएसओएन दो अलग-अलग प्रकार के डेटफॉर्मेट के साथ लौट रहा है। "dd MMM, yyyy" और "dd MMM, yyyy HH: mm: ss"जीसन टू जेसन रूपांतरण दो डेटफॉर्मेट

जब मैं निम्नलिखित के साथ JSON कन्वर्ट यह ठीक है:

Gson gson = new GsonBuilder().setDateFormat("MMM dd, yyyy").create(); 

लेकिन जब मैं विस्तृत दिनांक स्वरूप चाहते हैं और यह इस करने के लिए बदल गया है, यह फेंकता अपवाद com.google.gson.JsonSyntaxException: Mar 21, 2013

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

वहाँ एक रास्ता gson अपने Json रूपांतरण के लिए दो अलग-अलग DateFormat संभाल करने के लिए है?

उत्तर

60

मुझे एक ही समस्या का सामना करना पड़ रहा था।

new GsonBuilder().registerTypeAdapter(Date.class, new DateDeserializer()); 

private static final String[] DATE_FORMATS = new String[] { 
     "MMM dd, yyyy HH:mm:ss", 
     "MMM dd, yyyy" 
}; 


private class DateDeserializer implements JsonDeserializer<Date> { 

    @Override 
    public Date deserialize(JsonElement jsonElement, Type typeOF, 
      JsonDeserializationContext context) throws JsonParseException { 
     for (String format : DATE_FORMATS) { 
      try { 
       return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString()); 
      } catch (ParseException e) { 
      } 
     } 
     throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString() 
       + "\". Supported formats: " + Arrays.toString(DATE_FORMATS)); 
    } 
} 
2

कस्टम deserialization आवश्यक है। Apache Commons DateUtil का उपयोग करने के लिए एक सभ्य समाधान होगा, जो एक साथ कई दिनांक प्रारूपों को संभाल सकता है। इसके अलावा, जोडाटाइम एपीआई में एक समान सुविधा हो सकती है।

4

हालांकि इस सवाल का जवाब स्वीकार किया गया है मैं एक ऐसी ही अभी तक अधिक एक्स्टेंसिबल समाधान साझा करना चाहते थे: यहाँ कस्टम अक्रमांकन के माध्यम से मेरी समाधान है। आप gist here पा सकते हैं।

DateDeserializer.java

public class DateDeserializer<T extends Date> implements JsonDeserializer<T> { 

    private static final String TAG = DateDeserializer.class.getSimpleName(); 

    private final SimpleDateFormat mSimpleDateFormat; 
    private final Class<T> mClazz; 

    public DateDeserializer(SimpleDateFormat simpleDateFormat, Class<T> clazz) { 
     mSimpleDateFormat = simpleDateFormat; 
     mClazz = clazz; 
    } 

    @Override 
    public T deserialize(JsonElement element, Type arg1, JsonDeserializationContext context) throws JsonParseException { 
     String dateString = element.getAsString(); 
     try { 
      T date = mClazz.newInstance(); 
      date.setTime(mSimpleDateFormat.parse(dateString).getTime()); 
      return date; 
     } catch (InstantiationException e) { 
      throw new JsonParseException(e.getMessage(), e); 
     } catch (IllegalAccessException e) { 
      throw new JsonParseException(e.getMessage(), e); 
     } catch (ParseException e) { 
      throw new JsonParseException(e.getMessage(), e); 
     } 
    } 
} 

तब के रूप में विभिन्न स्वरूपों रजिस्टर ...

sGson = new GsonBuilder() 
        .registerTypeAdapter(Event.EventDateTime.class, 
          new DateDeserializer<Event.EventDateTime>(
            Event.EventDateTime.DATE_FORMAT, Event.EventDateTime.class)) 
        .registerTypeAdapter(Event.StartEndDateTime.class, 
          new DateDeserializer<Event.StartEndDateTime>(
            Event.StartEndDateTime.DATE_FORMAT, Event.StartEndDateTime.class)) 
        .registerTypeAdapter(Event.SimpleDate.class, 
          new DateDeserializer<Event.SimpleDate>(
            Event.SimpleDate.DATE_FORMAT, Event.SimpleDate.class)) 
        .create(); 

प्रत्येक प्रारूप तो एक वर्ग के लिए मैप किया गया है ...

public class Event { 

    @SerializedName("created") 
    private EventDateTime mCreated; 

    //@SerializedName("updated") 
    private EventDateTime mUpdated; 

    ... 

    @SerializedName("start") 
    private ConditionalDateTime mStart; 

    @SerializedName("end") 
    private ConditionalDateTime mEnd; 

    public static class ConditionalDateTime { 
     @SerializedName("dateTime") 
     private StartEndDateTime mDateTime; 

     @SerializedName("date") 
     private SimpleDate mDate; 

     public SimpleDate getDate() { 
      return mDate; 
     } 

     public StartEndDateTime getDateTime() { 
      return mDateTime; 
     } 

     /** 
     * If it is an all day event then only date is populated (not DateTime) 
     * @return 
     */ 
     public boolean isAllDayEvent() { 
      return mDate != null; 
     } 
    } 

    public static class EventDateTime extends Date { 
     public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 
    } 

    public static class StartEndDateTime extends Date { 
     public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ"); 
    } 

    public static class SimpleDate extends java.util.Date { 
     public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); 
    } 
} 
+0

बहुत अच्छा समाधान , और निश्चित रूप से अधिक विस्तार योग्य। –

+1

मुझे यह बहुत पसंद है, लेकिन मुझे आश्चर्य है कि क्या SimpleDateFormats और थ्रेड सुरक्षा में कोई समस्या हो सकती है। यदि ऐसा है, तो इसके बजाय प्रारूप स्ट्रिंग को स्टोर करने के लिए सबसे सरल हो सकता है, और प्रत्येक कॉल में DateDeserializer.deserialize() पर एक नया SimpleDateFormat बनाएं? –

संबंधित मुद्दे