2010-03-28 6 views
3

J'analyse certaines valeurs d'un fichier XML. Il y a une chaîne @"25-12-2010'T'23:40:00" avec l'heure et la date et il y a une chaîne avec le décalage GMT comme ceci @ "+ 0200". Donc l'heure ci-dessus est le 25. décembre 23:40:00 dans timeZone +0200 GMT. (ou 21:40 UTC) J'ai beaucoup de ces dates avec différents décalages GMT. Je dois afficher ces dates comme ils sont, c'est-à-dire qu'ils ne doivent pas être changés pour s'adapter aux paramètres régionaux de l'utilisateur. Donc, si le temps 1: est 22:45 +0500 alors c'est ce que je dois montrer à l'utilisateur, même si l'utilisateur est dans un fuseau horaire différent.NSDate dateFromString, comment analyser 'autour' UTC, GMT et les paramètres régionaux de l'utilisateur?

J'ai toutes sortes de problèmes avec l'affichage, le calcul et l'analyse de ces chaînes.

Si j'utilise un DateFormatter et dateFromString l'utilisateur des informations spécifiques GMT sera inclus dans le résultat NSDate ce qui signifie ce qui précède sera enregistrée en tant 23:40:00 +0100 GMT parce que c'est mon téléphone et peut-être de réglage 23h40: 00 -0400 sur un utilisateur du nouveau téléphone de New York. Lorsque je fais ensuite la soustraction, l'addition et la comparaison entre ces dates, je dois garder le décalage GMT et tout s'aggrave si le téléphone change les paramètres régionaux, de la date à laquelle la date est affichée ...

Existe-t-il un moyen pour moi d'extraire cette date de la chaîne comme UTC, puis l'enregistrer comme un intervalle au lieu d'une date réelle (dépendant de la fuseau horaire). Je sais que c'est ainsi que les dates sont toujours sauvegardées en interne. Mais je ne peux pas comprendre comment le faire avec la chaîne GMT séparée et en tenant compte des paramètres régionaux des utilisateurs.

Vive

Répondre

4

Utilisez setTimeZone: de NSDateFormatter. Vous devrez également stocker les décalages de fuseau horaire séparément du NSDate pour afficher plus tard les heures dans ces fuseaux horaires.

+0

Bonjour Ole Merci pour l'entrée. Comment utiliser setTimeZone? Comme je peux le voir à partir des docs, il est possible de définir un timeZone sur un formateur (par secondesFromGMT dans mon cas) Ensuite, je dois formater mon format de date pour chaque date Im affichage? La date est toujours enregistrée en tant qu'heure locale et tous les calculs que j'effectue entre ces dates impliqueraient la variable GMT et réduiraient tout au format UTC avant toute manipulation de date. J'imagine qu'écrire une catégorie sur NSDate et faire les calculs à la main en fonction du décalage GMT que je dois sauvegarder serait plus facile. Ou avez-vous raté ce à quoi vous faisiez référence? – RickiG

+0

Non, vous vous êtes trompé. NSDate ne connaît pas les fuseaux horaires, il stocke toujours les dates d'une manière indépendante du fuseau horaire (comme une période de temps depuis une date de référence spécifique). Donc, vos calculs ne seraient pas affectés. Maintenant, chaque fois que vous devez analyser une date ou en afficher une, vous devez configurer un NSDateFormatter et définir son fuseau horaire sur le bon fuseau horaire (par exemple, le fuseau horaire dans lequel la date doit être analysée ou la date affichée). –

4

Merci Ole. J'ai enfin compris que NSDate et NSDateformatter ne sont que des concepts abstraits et qu'une "date" est vraiment enregistrée en "millisecondes ou secondes depuis 1/1 2001" en interne.

J'ai fait un "Proof of concept" pour vraiment le comprendre. Maintenant, il est soudainement très simple d'écrire des catégories sur NSDate pour s'assurer que les dates entrées et sorties sont correctement formatées, mais tous les calculs sont faits à la date UTC brute.

- (void) testGMTDateParser { 

    NSMutableArray *arrayDates = [NSMutableArray arrayWithCapacity:5]; 
    [self setParsedDates:arrayDates]; 

    NSMutableArray *arrayGMTOffsets = [NSMutableArray arrayWithCapacity:5]; 
    [self setParsedGMTOffsets:arrayGMTOffsets]; 

    NSString *date00 = @"2010-03-30T12:00:00"; 
    NSString *GMT00  = @"-2"; 

    NSString *date01 = @"2010-03-30T12:00:00"; 
    NSString *GMT01  = @"-1"; 

    NSString *date02 = @"2010-03-30T12:00:00"; 
    NSString *GMT02  = @"+0"; 

    NSString *date03 = @"2010-03-30T12:00:00"; 
    NSString *GMT03  = @"+1"; 

    NSString *date04 = @"2010-03-30T12:00:00"; 
    NSString *GMT04  = @"+2";  

    NSArray *dateArray = [NSArray arrayWithObjects:date00, date01, date02, date03, date04,nil]; 
    NSArray *GMTArray = [NSArray arrayWithObjects:GMT00, GMT01, GMT02, GMT03, GMT04, nil]; 

    for (int i = 0; i < [dateArray count]; i++) { 

     [self parseDateString:[dateArray objectAtIndex:i] withGMTString:[GMTArray objectAtIndex:i]]; 
    } 

} 

Analyser les dates en fonction de leur décalage GMT respectif. Cela s'assurera que l'heure UTC enregistrée en interne est correcte.

-(void) parseDateString:(NSString*) dateString withGMTString:(NSString*) GMTString { 

    NSInteger hoursFromGMT  = [GMTString intValue]; 
    NSInteger secondsFromGMT = (hoursFromGMT * 60 * 60); 

    NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:secondsFromGMT]; 

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

    [self.parsedDates addObject:date]; 
    [self.parsedGMTOffsets addObject:[NSNumber numberWithInt:secondsFromGMT]]; 
} 

Configurez le format NSDate pour imprimer les dates enregistrées en ce qui concerne le décalage GMT. toutes les dates peuvent maintenant être manipulées comme UTC sans égard à GMT.

-(void) printOutDates { 

    for (int i = 0; i < [self.parsedDates count]; i++) { 

     NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:[[parsedGMTOffsets objectAtIndex:i] intValue]]; 

     NSDateFormatter *dateFormatterGMTAware = [[NSDateFormatter alloc] init]; 
     [dateFormatterGMTAware setTimeZone:timeZone]; 
     [dateFormatterGMTAware setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"]; 

     NSLog(@"%@ in Original GMT", [dateFormatterGMTAware stringFromDate:[parsedDates objectAtIndex:i]]); 
     NSLog(@"%@ in Local GMT\n\n", [parsedDates objectAtIndex:i]); 
    } 
} 

2010-03-30 18: 50: 31,284 TimeZonePOC [39830: 207] 2010-03-30 12:00:00 -0200 Titre original GMT 2010-03-30 18: 50: 31.285 TimeZonePOC [39830: 207] 2010-03-30 16:00:00 +0200 en local GMT

2010-03-30 18:50:31.287 TimeZonePOC [39830: 207] 2010-03-30 12:00:00 -0100 dans Original GMT 2010-03-30 18: 50: 31.287 TimeZonePOC [39830: 207] 2010-03-30 15:00:00 + 0200 en local GMT

2010-03-30 18: 50: 31,289 TimeZonePOC [39830: 207] 2010-03-30 12:00:00 +0000 Titre original GMT 2010-03-30 18:50 : 31,289 TimeZonePOC [39830: 207] 2010-03-30 14:00:00 +0200 en local GMT

2010-03-30 18: 50: 31,290 TimeZonePOC [39830: 207] 2010-03-30 12:00:00 +0100 en GMT d'origine 2010-03-30 18: 50: 31.292 TimeZonePOC [39830: 207] 2010-03-30 13:00:00 +0200 en GMT local

2010-03-30 18: 50: 31,292 TimeZonePOC [39830: 207] 2010-03-30 12:00:00 GMT 0200 Titre original 2010-03-30 18: 50: 31,294 TimeZonePOC [39830 : 207] 2010-03-30 12:00:00 +0200 en local GMT