Frage

mit NSDateFormatter ein RFC3339 Datum Parsen scheint unmöglich zu sein, im allgemeinen Fall. Liege ich falsch? [Edit 2 Jahre später: Es gibt jetzt auch ein Weg! Siehe unten und Fußnote.]

Ein nicht besonders verformbares Webservice mir füttert Daten wie:

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

RFC3339-konform, Standardausgabe der jaxb Bibliothek sie verwenden. Beachten Sie den Doppelpunkt, die RFC3339 erfordert, wenn der Offset ist nicht eine wörtliche "z":

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

Ich möchte diese in NSDates analysieren.

will NSDateFormatter Muster in der Syntax angegeben von Unicode , die Angebote Datumsfeld Symbole für Zeitzonen wie "PDT", "-0800", "GMT-08: 00", aber nicht "-08: 00".

googeln und andere ähnliche SO Fragen, produzieren nur Datumsformate wie

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

Die letztere, von denen eine wörtliche „Z“ erfordert, und der ehemalige besteht entweder das Fehlen eines Kolon oder in Gegenwart eines „GMT“. Aber sie schien Arbeit vor ios 4.x (möglicherweise durch die tz Verwerfen Offset vollständig;. Meine Daten sind nicht klar)

Meine Optionen an diesem Punkt sind leider viel:

  • entdeckt einige undokumentierte Formatbezeichner oder einigen seltsamen Modus NSDateFormatter in stellen, dass das Streu Kolon akzeptieren: gewagtes Spiel, wahrscheinlich nicht existent. [Fußnote]
  • überzeugen meinen Dienst Verleger alle Termine in zulu Zeit zu drehen, und geben Sie ‚Z‘:. Politisch herausfordernde
  • schriebe meine eigene NSFormatter Unterklasse oder Forschung guten alten strptime_l: Arbeit. :)
  • string-manipulieren meine Eingabe und Streifen der letzten Doppelpunkt. Spröde und hässlich, aber der wahrscheinliche Weg des geringsten Widerstands

verstanden habe ich die Situation genau, dass die aktuellen NSDateFormatter ohne Erweiterungen Unicode streng folgt; und die Unicode-Formate sind nicht ausreichend, um vollständig ein RFC3339 Datum zu beschreiben?

[FUSSNOTE] Ich komme zurück zu diesen drei Jahren später zu tack auf einem kleinen Zusatz: Unicode und Apple haben diese Funktion zu den Formatstrings hinzugefügt, wie von iOS6 / OSX10.8. Vergleichen Sie Die neueste Version zum Zeitpunkt des Schreibens mit sein unmittelbarer Vorgänger , und notieren Sie die Zugabe von 5 "Z" s, die Ausbeuten ein Zonenformat wie „-08: 00“. Also, wenn Sie Unterstützung wegkommen kannst mit Notwasserung für 5.x / 10.7, gibt es einen neuen richtigen Weg, es zu tun. Ich werde die vorherige Antwort Stand verlassen, wie es ist immer noch der beste Ansatz, wenn die Abwärtskompatibilität erforderlich ist.

War es hilfreich?

Lösung

Datum Zeichenfolge in Cocoa Parsen kann ein Schmerz, vor allem, wenn Sie mit Daten von .NET-basierten Web-Services erzeugt zu tun haben.

Ich würde vorschlagen, an der NSDate + InternetDateTime Kategorie suchen, dass Michael Wasserfall hat auf NSDate als Teil seines MWFeedParser Projekt auf GitHub. Es funktioniert gut für mich genau das Format Datum Parsen Sie beschreiben.

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

Andere Tipps

- getObjectValue: forString: Bereich: Fehler: kann tatsächlich Parse RFC3339 Termin richtig. Ich habe keine Ahnung, warum - dateWithString: können sie nicht:

// 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];

Die String-Format Zeichen sind nirgendwo in der Apple-Dokumentation dokumentiert. Stattdessen gibt es einen Link tief in irgendeinem Dokument zeigt auf den Standard Unicode versteckt in

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

zu diesem Link, um die Informationen verwenden ist es ganz einfach:

- (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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top