web-dev-qa-db-fra.com

Existe-t-il un moyen simple de convertir un horodatage ISO8601 en une NSDate formatée?

Si j'utilise le code suivant:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];   
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
NSDate *myDate = [dateFormatter dateFromString:@"2010-01-28T15:22:23.863"];
NSLog(@"%@", [dateFormatter stringFromDate:myDate]);

Il est converti avec succès en un objet Date, cependant, je n'arrive pas à le formater autrement que yyyy-MM-dd'T'HH:mm, c'est-à-dire que ce qui est enregistré est 2010-01-28T15:22:23

Si je change la dateFormat pour dire [dateFormatter setDateFormat:@"yyyy-MMMM-d'T'HH:mm"]; l'objet Date est nul ...

Donc, ma question ultime est de savoir comment formater un horodatage ISO8601 à partir d'une base de données SQL pour utiliser, par exemple, NSDateFormatterMediumStyle pour retourner "1er janvier 2010"?

46
rson

Vous avez besoin d'un autre formateur pour gérer la sortie. Mettez ceci après votre code:

NSDateFormatter *anotherDateFormatter = [[NSDateFormatter alloc] init];   
[anotherDateFormatter setDateStyle:NSDateFormatterLongStyle];
[anotherDateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [anotherDateFormatter stringFromDate:myDate]);
19
osteven

J'ai un problème similaire mais légèrement plus complexe et j'ai trouvé une solution très simple!

Le problème: Mes dates ISO8601 entrantes ressemblent à ceci: 2006-06-14T11:06:00+02:00 Ils ont un décalage de fuseau horaire à la fin.

La solution: Utilisez Peter Hosey ISO8601DateFormatter que vous pouvez télécharger depuis - ici .

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSDate *theDate = [formatter dateFromString:dateString];
[formatter release], formatter = nil;

et

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSString *dateString = [formatter stringFromDate:[Twitch dateTwitched]];
[formatter release], formatter = nil;
42
Matthew

Voici un exemple de code d'Apple

    NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate *date = [formatter dateFromString:dateString];

lien : https://developer.Apple.com/library/ios/#qa/qa1480/_index.html

19
david

Juste pour mentionner que depuis iOS 6.0, vous pouvez utiliser ce format:

 yyyy-MM-dd'T'HH:mm:ssZZZZZ
12
Marcin

J'ai une implémentation C très rapide de l'analyse syntaxique de NSStrings ISO8601 en NSDates dans SAMCategories . Vous pouvez l'installer avec CocoaPods ou simplement copier les fichiers dans votre projet.

Voici comment l'utiliser:

[NSDate sam_dateFromISO8601String:@"2013-08-24T06:51:21-07:00"]

Il est très robuste et prend en charge les fuseaux horaires manquants, etc. Comme mon commentaire ci-dessus a dit, NSDateFormatter était très lent pour moi lors de l'analyse de nombreuses dates. Le passage à cette implémentation a aidé énormément.

Ce code est utilisé dans 6 applications de production (y compris Hipstamatic et Roon ) sur lesquelles j'ai travaillé sans problème connu. Il y a suite de tests pour empêcher la régression.

En bref, je pense que c'est la meilleure façon d'analyser les chaînes ISO8601 dans Objective-C.


Un petit côté, si vous êtes préoccupé par les performances et le transfert, l'envoi de nombres entiers au lieu de chaînes ISO8601 est grandement préféré. Vous pouvez simplement les convertir en dates avec [NSDate dateWithTimeIntervalSince1970:yourInteger]. Les performances sont aussi rapides que possible et il y a moins de caractères à transférer sur le fil.

6
Sam Soffes

Je dois noter que la dernière fois que j'ai vérifié les méthodes Apples NSDate ne prenaient pas en charge ISO8601. J'ai toujours un bug avec Apple à propos de la prise en charge officielle.

+ (id)dateWithNaturalLanguageString:(NSString *)string

va correctement (la dernière fois que je l'ai exécuté) analyser et créer un objet NSDate à partir d'une chaîne ISO801, bien que la documentation dise que vous ne devriez pas l'utiliser, cela a fonctionné sur toutes les dates ISO8601 que j'ai essayées jusqu'à présent.

5
Colin Wheeler

La réponse @danielbeard a fonctionné pour moi. Cependant, vous devez inclure le fuseau horaire, sinon il convertit une date UTC en votre fuseau horaire actuel, ce qui n'est pas ce que vous voulez.

- (NSDate *) dateFromISO8601DateString:(NSString *) dateString {
    NSDateFormatter * dateFormatter = [NSDateFormatter new];
    dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate * date = [dateFormatter dateFromString:dateString];
    return date;
}
3
gngrwzrd

@Thread captain Essayez ce format: "aaaa-MM-jj'T'HH: mm: ss.SSS"

2
Andi Utzinger