Question

Ecrire une application iPhone en Objective-C, j'ai une date sous forme de chaîne (au format UTC, avec un Z à la fin pour indiquer zéro décalage horaire UTC ou temps zulu), que je dois analyser dans un objet NSDate .
Un peu de code:

NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSString* str = @"2009-08-11T06:00:00.000Z";
NSDate* date = [df dateFromString:str];
En l'utilisant le débogueur, date finit par nil! Je suppose qu'il a quelque chose à voir avec ma chaîne de format de date.
Comment puis-je fixer pour analyser correctement la chaîne de date?
Une pensée serait de faire le Z au format littéral de date, à la définition du format de date à yyyy-MM-dd'T'HH:mm:ss.SSS'Z'.
Cela fonctionne, sauf lorsque le Z est analysé comme un littéral, la date perd des informations de décalage, et est donc ambiguë, et donc interprété l'heure locale.
Par exemple, si la chaîne était à analyser 2009-08-11T06: 00: 00.000Z (06h00 heure zulu), il serait interprété comme 06h00 heure locale, et un décalage incorrect serait alors appliqué. Il serait alors analysée comme 2009-08-11T06: 00: 00,000 à 600 (12:00 zulu) avec le décalage en fonction du décalage de l'utilisateur
. Merci!

Était-ce utile?

La solution

J'ai eu ce problème aussi, je ne suis pas sûr que ce soit un bug de l'API dans le code d'Apple, ou mon manque de compréhension, mais j'ai travaillé autour d'elle en utilisant des décalages d'heure dans mes chaînes de date.

Si vous modifiez le code dans votre exemple:

NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSString* str = @"2009-08-11T06:00:00.000-0700";   // NOTE -0700 is the only change
NSDate* date = [df dateFromString:str];

Il analysera maintenant la chaîne de date. Bien sûr, les heures -0700 est mon offset, vous auriez à changer à la vôtre. Espérons que cela aide.

Autres conseils

La plupart des réponses que vous suggèrent de traiter « Z » comme un caractère littéral. Ne faites pas cela!

Le Z signifie en fait que la date est compensée par 0 à UTC (+0000).

Ceci est selon le format le fuseau horaire ISO8601 :

  

ISO 8601 temps format zone: Une constante, spécifique décalée par rapport à UTC, qui a toujours le même format, sauf UTC lui-même ( "Z")

.      

"- 08:00"

     

"Z"

Qu'est-ce que vous voulez faire est d'utiliser le format suivant pour votre NSDateFormatter:

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                                  // 2013-11-18T23:00:00.324Z
                                  [formatter setTimeZone:[NSTimeZone localTimeZone]];
                                  [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
                                  return formatter;

En répétant la Z cinq fois, vous dites au formatter d'utiliser ISO8601 lors de l'analyse de la chaîne.

Bonus:

  • Utilisez une à trois Z s pour format RFC 822 GMT.
  • Utilisez quatre Z s pour localisée format GMT.

Pour plus d'informations, consultez ce document .

Je pense que vous avez besoin de mettre des guillemets simples autour de la Z dans la chaîne de format, parce que le Z signifie réellement quelque chose à la formatter et que vous voulez qu'il représente un caractère littéral au lieu.

    [df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

Il n'y a pas besoin de manipuler la chaîne. Il suffit de régler le fuseau horaire sur la NSDateFormatter (et les paramètres régionaux pendant que vous y êtes):

NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setLocale:[NSLocale systemLocale]];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

Et analyser les chaînes de date au besoin:

NSDate * value = [formatter dateFromString:@"2012-03-01T23:08:25.000Z"];
NSLog(@"%@", value); // prints 2012-03-01 23:08:25 +0000

Vous pouvez utiliser cette méthode pour obtenir la date de l'UTC.

+ (NSDate*)getDateFromUTCDateTimeString:(NSString*)dateString {

NSDateFormatter *isoDateFormatter = [[NSDateFormatter alloc] init];

[isoDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

[isoDateFormatter setTimeZone:[NSTimeZone  timeZoneWithAbbreviation:@"UTC"]];

NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];

[userFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

[dateFormatter setTimeZone:[NSTimeZone  timeZoneWithAbbreviation:@"UTC"]];

NSDate *date = [isoDateFormatter dateFromString:dateString];

return [dateFormatter dateFromString:[userFormatter stringFromDate:date]];

}

cela peut vous aider .. le « Z » est un littéral pour le code temporel de la zone. essayez d'utiliser « o » (la lettre, non nul). Le littéral « o » signifie le décalage UTC. Je suis tombé sur ce un moment, je l'espère, cela vous a aidé.

-(NSDate*)dateFromZulu:(NSString*)str {
    if (str == nil) {
        NSLog(@"Error getting date");
        return [NSDate date];
    }

    NSDateFormatter *f = [[NSDateFormatter alloc] init];
    [f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss Z"];
    NSDate *ret = [f dateFromString:[str stringByReplacingOccurrencesOfString:@"Z" withString:@" +0000"]];
    [f release];

    if (ret == nil) {
        ret = [NSDate date];
        NSLog(@"Error formatting date (%@)",str);       
    }   
    return ret;     
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top