2010-12-01 8 views
17

सामान्य मामले में NSDateFormatter के साथ एक आरएफसी 3339 तारीख को पार करना असंभव प्रतीत होता है। क्या मै गलत हु? [2 साल बाद संपादित करें: अब एक रास्ता है! ।आईएसओ 4.x और मैकोज़ एक्स 10.6 में NSDateFormatter के साथ rfc3339 तारीखों को पार्स करना असंभव है?

2009-12-31T00:00:00-06:00 

Rfc3339 शिकायत है, वे का उपयोग कर रहे JAXB पुस्तकालय के डिफ़ॉल्ट उत्पादन: नीचे और फुटनोट देखें]

एक नहीं, खासकर-लचीला वेब सेवा मुझे खिला है की तरह तिथियाँ।

time-numoffset = ("+"/"-") time-hour ":" time-minute 
time-offset  = "Z"/time-numoffset 

मैं NSDates में इन पार्स करने के लिए करना चाहते हैं: पेट, जो rfc3339 की आवश्यकता है जब ऑफसेट एक शाब्दिक "Z" नहीं है ध्यान दें।

NSDateFormatter Unicode द्वारा निर्दिष्ट वाक्यविन्यास में पैटर्न चाहता है, जो "पीडीटी", "-0800", "जीएमटी -08: 00" जैसे समय क्षेत्र के लिए दिनांक फ़ील्ड प्रतीकों की पेशकश करता है लेकिन "-08: 00" नहीं।

Googling, और अन्य समान अतः सवाल, जैसे

[myDateParser setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"]; 
/* or: */ [myDateParser setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"]; 

बाद वाले का एक शाब्दिक "Z" की आवश्यकता है, और पूर्व का कहना है या तो एक बृहदान्त्र या की उपस्थिति के अभाव केवल तिथि प्रारूप का उत्पादन एक " GMT"। हालांकि, वे ios 4.x से पहले काम करने के लिए दिखाई दिया (संभवतः को त्यागकर TZ पूरी तरह से भरपाई द्वारा, मेरे डेटा स्पष्ट नहीं हैं।)

इस बिंदु पर मेरे विकल्प एक खेद बहुत हैं:

  • कुछ की खोज अनियंत्रित प्रारूप विनिर्देशक, या NSDateFormatter को रखने के लिए कुछ अजीब मोड, जो भटक ​​कॉलन स्वीकार करेंगे: लम्बा शॉट, संभवतः कोई भी नहीं। [फुटनोट]
  • मेरी सेवा प्रकाशक को सभी तिथियों को ज़ुलू समय में बदलने और 'जेड' निर्दिष्ट करने के लिए राजी किया: राजनीतिक रूप से चुनौतीपूर्ण।
  • अपना स्वयं का एनएसएफॉर्मेटर सबक्लास लिखें या अच्छे पुराने strptime_l पर शोध करें: काम करें। :)
  • स्ट्रिंग-मेरे इनपुट में हेरफेर करें और अंतिम कोलन को पट्टी करें: भंगुर और बदसूरत, लेकिन कम से कम प्रतिरोध का संभावित मार्ग।

क्या मैंने स्थिति को सटीक रूप से समझा है, वर्तमान एनएसडीएटीफॉर्मेटर बिना विस्तार के यूनिकोड का पालन करता है; और यूनिकोड प्रारूप आरएफसी 3339 दिनांक पूरी तरह से वर्णन करने के लिए अपर्याप्त हैं?

[फुटनोट] मैं वापस इस तीन साल के लिए आते हैं बाद में एक छोटा सा परिशिष्ट पर हमले के लिए: यूनिकोड और एप्पल iOS6/OSX10.8 के रूप में, प्रारूप तार करने के लिए इस सुविधा को शामिल किया है। The latest revision as of this writingits immediate predecessor के साथ तुलना करें, और 5 "ज़ेड" के अतिरिक्त नोट करें, जो "-08: 00" जैसे ज़ोन प्रारूप उत्पन्न करता है। तो यदि आप 5.x/10.7 के लिए डचिंग समर्थन से दूर हो सकते हैं, तो ऐसा करने का एक नया सही तरीका है। मैं पिछला उत्तर स्टैंड छोड़ दूंगा, क्योंकि पिछड़ा संगतता आवश्यक होने पर यह अभी भी सबसे अच्छा तरीका है।

उत्तर

8

कोको में दिनांक स्ट्रिंग पार्सिंग दर्द हो सकती है, खासकर यदि आपको .NET आधारित वेब सेवाओं द्वारा उत्पन्न तिथियों से निपटना है।

मैं एनएसडीएटी + इंटरनेटडेटाइम श्रेणी को देखने का सुझाव दूंगा कि माइकल वाटरफॉल ने जीएसबीबी पर अपने MWFeedParser प्रोजेक्ट के हिस्से के रूप में एनएसडीएटी पर है। यह आपके लिए वर्णन की गई तारीख के बिल्कुल प्रारूप को पार्स करने के लिए अच्छा काम करता है।

https://github.com/mwaterfall/MWFeedParser/

+0

सूचक के लिए धन्यवाद - मैं में देखा उसकी स्रोत, और आप क्या जानते हैं, विकल्प 4 (अंतिम कोलन हटाएं) ठीक वही है जो यह करता है। चूंकि यह उनके लिए काम करता है, इसलिए शायद मैं उनके उदाहरण का पालन करूंगा। – rgeorge

11

- getObjectValue: forString: सीमा: त्रुटि: वास्तव में RFC3339 सही ढंग से तारीखें पार्स कर सकते हैं। नहीं कर सकते हैं:

// RFC3339 date formatting 
NSString *dateString = @"2012-04-11T18:34:19+00:00"; 
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ"; 

NSDate *date; 
NSError *error; 
[formatter getObjectValue:&date forString:dateString range:nil error:&error]; 
+0

मेरे पास वास्तव में यहां सुधार करने के लिए कुछ भी नहीं है और उस तारीख को इंगित करने के लिए पोस्टर (sc0rp10n) का शुक्रिया अदा करना चाहता था। फ्रॉमस्ट्रिंग: getObjectValue: करता है, जबकि इस तरह की तिथियों के साथ काम नहीं करता है। यह मुझे पागल कर रहा है और मैं getObjectValue को आजमाने की कोशिश कर रहा था: ताकि मैं समय क्षेत्र भाग को छोड़कर एक सीमा निर्दिष्ट कर सकूं। आपके सुझाव ने मुझे बचाया। धन्यवाद। –

5

स्ट्रिंग प्रारूप पात्रों एप्पल दस्तावेज में कहीं नहीं प्रलेखित dateWithString - मैं पता नहीं क्यों है। इसके बजाय वहाँ उस लिंक पर

http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns

पर एक लिंक यूनिकोड मानक के लिए कुछ दस्तावेज की ओर इशारा करते में गहरी छुपा जानकारी का उपयोग यह है काफी सरल है:

- (NSDate*)dateFromRFC3339String:(NSString*)aString 
{ 
    static NSDateFormatter* sRFC3339DateFormatter = nil; 
    static NSDateFormatter* sRFC3339DateFormatterSubSeconds = nil; 
    static dispatch_once_t onceToken; 

    dispatch_once(&onceToken, ^{ 
     NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 

     sRFC3339DateFormatter = [[NSDateFormatter alloc] init]; 
     [sRFC3339DateFormatter setLocale:enUSPOSIXLocale]; 
     [sRFC3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssXXXXX"]; 
     [sRFC3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 

     sRFC3339DateFormatterSubSeconds = [[NSDateFormatter alloc] init]; 
     [sRFC3339DateFormatterSubSeconds setLocale:enUSPOSIXLocale]; 
     [sRFC3339DateFormatterSubSeconds setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSSSSXXXXX"]; 
     [sRFC3339DateFormatterSubSeconds setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 
    }); 

    NSDate* date = [sRFC3339DateFormatter dateFromString:aString]; 
    if (date == nil) 
     date = [sRFC3339DateFormatterSubSeconds dateFromString:aString]; 

    return date; 
} 
+0

हां, 'एक्स' ... प्रारूपों का परिवार आईओएस 7 (tr35-31।) 'ZZZZZ' द्वारा समर्थित स्पेक के संस्करण में जोड़ा गया है 'xxxXX' के बराबर परिभाषित किया गया है और आईओएस 6 में परिभाषित है (परिभाषित tr35-25), इसलिए इस विशेष आवेदन के लिए मैं पूर्व की सिफारिश करता हूं। – rgeorge

+1

XXXXX और ZZZZZ आरएफसी 3339 की तुलना में अधिक उदार हैं क्योंकि वे समय क्षेत्र में सेकंड की अनुमति देते हैं। XXX spec के सबसे नज़दीकी है (यानी, यह ज़ेड और ऑफसेट्स -08: 00 की तरह अनुमति देता है)। –

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