2013-02-16 49 views
9

में मैं नीचे की तरह दो क्षेत्र (वेतन ध्यान है कि पहले क्षेत्र मिलीसेकेंड अनुभाग है) है:DateFormat पैटर्न "yyyy-MM-dd'T'HH: mm: ss.SSS'Z '" Gson

{ 
    "updateTime":"2011-11-02T02:50:12.208Z", 
    "deliverTime":"1899-12-31T16:00:00Z" 
} 

मैं Gson के साथ एक वस्तु के लिए JSON स्ट्रिंग deserialize करना चाहते हैं, तो मैं एक Gson उदाहरण मिलता है:

GsonBuilder gb = new GsonBuilder(); 
gb.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 
gson = gb.create(); 

पहले क्षेत्र जावा दिनांक प्रकार के deserialized है: 2011-11-02 02:50 : 12.208 (टीआई को नजरअंदाज करने जैसा दिखता है मुझे जोन सेक्शन-'Z ', जिसकी मुझे उम्मीद है)। हालांकि, दूसरा क्षेत्र 1 9 00-01-01 00:00:00 (मैं चीन में रहता हूं, यहां +8 जीएमटी) में deserialized है, ऐसा लगता है कि समय क्षेत्र खंड-'Z 'deserialization में एक भूमिका निभाता है।

दूसरा फ़ील्ड समय क्षेत्र अनुभाग का उपयोग क्यों करता है? यह मेरी अपेक्षा नहीं है।

+0

मेरे लिए यह दूसरी तारीख स्ट्रिंग को पार्स करने में विफल रहता है ('java.text.ParseException: अवांछित दिनांक:" 1899-12-31T16: 00: 00Z "')। आप किस जीसन का उपयोग कर रहे हैं? –

+0

आप सरल उद्धरणों में टी और जेड को क्यों संलग्न करते हैं? मैं नहीं (जीसन 1.7.1) –

+0

बस आपको अधिक फीडबैक देने के लिए, मेरा पैटर्न एमएम/डीडी/वाई एचएच: मिमी: एसएस एसएसएसजेड मुझे इस तरह की तारीख देता है: 02/20/13 18:03:11 08 9 + 0100 –

उत्तर

12

त्वरित जवाब

पहले स्ट्रिंग सही तरीके से अपने दिनांक स्वरूप और आपके स्थानीय समय क्षेत्र का उपयोग कर, एक दूसरे यह सम्मान नहीं करता है, तो एक डिफ़ॉल्ट SimpleDateFormat वस्तु मिलीसेकेंड नहीं है कि द्वारा पार्स किया जाएगा (पार्स किया गया है "yyyy -MM-dd'T'HH: mm: ss'Z 'पार्स प्रारूप पूर्ण जवाब

पूरी तरह से करने के लिए प्रतिक्रिया करने के लिए है) और आप एक "बदलाव" समय भाग में दे रही है यूटीसी-क्षेत्र का उपयोग

। आपका सवाल आपको गोता लगाने की जरूरत है जीसन स्रोत कोड में। विशेष रूप से आपको DefaultDateTypeAdapter का कोड देखना होगा जिसका उपयोग दिनांकों को पार्स करने के लिए किया जाता है। आप यह सब कोड link पर पा सकते हैं, लेकिन त्वरित संदर्भ के लिए मैं यहां सबसे प्रासंगिक भागों की प्रतिलिपि बनाउंगा।

जब आप बिल्डर में इस फोन:

gb.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 

आप इस तरह से एक DefaultDateTypeAdapter आरंभ कर रहे हैं:

DefaultDateTypeAdapter(DateFormat enUsFormat, DateFormat localFormat) { 
    this.enUsFormat = enUsFormat; 
    this.localFormat = localFormat; 
    this.iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); 
    this.iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC")); 
} 

जहां:

  1. enUsFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") और
  2. localFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US)

जब आप निर्माता में पारित स्ट्रिंग के बाद से।

ध्यान दें कि Locale.US एक टाइमज़ोन नहीं है और iso8601FormatenUsFormat के समान मिलीसेकंड के बिना ही यूटीसी टाइमज़ोन के साथ है।

private Date deserializeToDate(JsonElement json) { 
    synchronized (localFormat) { 
     try { 
     return localFormat.parse(json.getAsString()); 
     } catch (ParseException ignored) { 
     } 
     try { 
     return enUsFormat.parse(json.getAsString()); 
     } catch (ParseException ignored) { 
     } 
     try { 
     return iso8601Format.parse(json.getAsString()); 
     } catch (ParseException e) { 
     throw new JsonSyntaxException(json.getAsString(), e); 
     } 
    } 
    } 

जहां तीन तिथि प्रारूप के सभी एक झरने के दृष्टिकोण में इस्तेमाल कर रहे हैं:

पार्सिंग deserializeToDate विधि में होता है।

प्रथम जेसन स्ट्रिंग: "2011-11-02T02: 50: 12.208Z"। इसे localFormat द्वारा तत्काल पार्स किया गया है क्योंकि मिलीसेकंड है और आपको वह परिणाम देता है जो आप अपने टाइमज़ोन का उपयोग करने की अपेक्षा करते हैं।

दूसरा जेसन स्ट्रिंग: "1899-12-31T16: 00: 00Z"। इसे localFormat द्वारा पार्स नहीं किया जाएगा क्योंकि मिलीसेकंड नहीं है, इसलिए दूसरा मौका enUsFormat है जो स्थानीय स्तर को छोड़कर समान पैटर्न है। तो यह वैसे ही असफल हो जाएगा। पार्स करने के लिए

अंतिम मौका: iso8601Format, कहीं भी होगी, यह तो यह यूटीसी के रूप में तिथि को पार्स होगा, जबकि दूसरों को अपने समय क्षेत्र का उपयोग कर पार्स, कोई मिलीसेकेंड, लेकिन, निर्माण के लिए, यह भी एक UTC समय क्षेत्र है।