web-dev-qa-db-fra.com

Comment analyser une chaîne de date dans un objet NSDate dans iOS?

J'essaie d'analyser une chaîne de date de xml dans un objet NSDate dans une application iPhone

Je sais que cela a dû être demandé auparavant, cependant, je pense avoir la bonne syntaxe, mais cela ne fonctionne pas. Y at-il un problème avec mon code?

La date que je dois analyser est la suivante:

2011-01-21T12:26:47-05:00

Le code que j'utilise pour l'analyser est le suivant:

self.dateFormatter = [[NSDateFormatter alloc] init];
    [self.dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    [self.dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
    [self.dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];



... 

else if([elementName isEqualToString:kUpdated]){
    self.currentQuestion.updated = [self.dateFormatter dateFromString:self.currentParsedCharacterData ];
}

Toute aide grandement appréciée. Merci!

** Sur la base de la référence de lien du ChisKent, j'ai résolu le problème de la manière suivante:

else if([elementName isEqualToString:kLastOnDeck]){

    NSString *dateStr = self.currentParsedCharacterData;
    // we need to strip out the single colon
    dateStr = [dateStr stringByReplacingOccurrencesOfString:@":" 
                                                 withString:@"" 
                                                    options:0 
                                                      range:NSMakeRange([dateStr length] - 5,5)];




    self.currentQuestion.lastOnDeck = [dateFormatter dateFromString:dateStr];

}
49
JohnRock

Vous n'avez pas besoin de presque autant de guillemets simples que vous avez (nécessaire uniquement pour les caractères non date/heure), changez donc ceci:

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

Pour ça:

[self.dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"];
...
self.currentQuestion.updated = [self.dateFormatter dateFromString:[self.currentParsedCharacterData stringByReplacingOccurrencesOfString:@":" withString:@"" options:0 range:NSMakeRange([self.currentParsedCharacterData length] – 5,5)]];

Documentation ici: https://developer.Apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//Apple_ref/doc/uid/TP40002369-SW1

Modèles de format Unicode: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns

Traiter les fuseaux horaires avec des deux-points (+00: 00): http://petersteinberger.com/2010/05/nsdateformatter-and-0000-parsing/

65
theChrisKent

Il m'a fallu un certain temps pour trouver la réponse simple à cela. et il y a beaucoup de solutions qui impliquent l'introduction de code tiers supplémentaire.

Pour ceux qui ont du mal à le faire maintenant et qui ne supportent que iOS 6 et supérieur.

Vous pouvez définir le formateur de date sur

[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]

Et cela traitera correctement le "-05: 00" avec les deux points.

3
ucangetit

J'avais les mêmes problèmes avec le côlon à la fin. Voici une fonction que j'ai utilisée pour normaliser la date afin de rendre NSDate heureux.

/**
 * Timezones are returned to us in the format +nn:nn
 * The date formatter currently does not support IS 8601 dates, so
 * we convert timezone from the format "+07:30" to "+0730" (removing the colon) which
 * can then be parsed properly.
 */
- (NSString *)applyTimezoneFixForDate:(NSString *)date {
    NSRange colonRange = [date rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@":"] options:NSBackwardsSearch];
    return [date stringByReplacingCharactersInRange:colonRange withString:@""];
}
3
Anurag

Les solutions sont à changer: 

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

À cette notation: 

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

j'espère que cela vous aidera.

1
Badre

Le problème est le "Z" à la fin. De la manière dont vous l'écrivez entre guillemets, votre analyseur s'attend à un caractère littéral Z dans votre chaîne temporelle, et il n'y en a pas. Ce que vous voulez, c'est le caractère de mise en forme Z sans guillemets, ce qui indique que votre chaîne de temps contient des informations de fuseau horaire. Le -05: 00 à la fin de votre chaîne correspond au fuseau horaire. 

Étant donné que vous attendez des informations sur le fuseau horaire, il est plutôt inutile de définir le fuseau horaire dans votre formateur de date. Et vérifiez le lien vers les modèles de formatage Unicode, ce lien contient les informations définitives auxquelles vous devez faire confiance au-dessus de toutes les réponses que vous obtenez ici. 

1
gnasher729

ISO8601DateFormatter

J'ai eu beaucoup de succès avec cette bibliothèque disponible en tant que CocoaPod.

https://github.com/boredzo/iso-8601-date-formatter

Usage

- (ISO8601DateFormatter *)dateFormatter
{
    static ISO8601DateFormatter *dateFormatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dateFormatter = [[ISO8601DateFormatter alloc] init];
        dateFormatter.includeTime = YES;
    });

    return dateFormatter;
}


NSDate *date = [[self dateFormatter] dateFromString:@"2015-05-09T13:06:00"];

À partir de iOS 10, le système fourni NSISO8601DateFormatter est disponible pour ce format particulier.

0
BergQuester