2017-03-03 3 views
1

Je possède ce morceau de codeNSDateComponents retour résultat inattendu

NSDateComponents *comps = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:sender.date]; 
[comps setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]]; 
NSDate *converted = [[NSCalendar currentCalendar] dateFromComponents:comps]; 

Sender.date peut être à la console comme sortie

1963-02-23 12:00:00 +0000 heures du matin

Mais comps.day pour UTC me donne 22 que je devrait être 23 t depuis chapeau valeur de l'expéditeur UTC est évidemment composante contenant jour égal à 23.

Est-ce en quelque sorte lié à 12 h? Qu'est-ce que j'oublie ici?

Merci!

+1

Il est dit '22', parce qu'il vous a montrer dans votre propre fuseau horaire, alors que la chaîne vous montrais la date GMT/UTC/Zulu. – Rob

+0

Tenir compte utiliser simplement 'NSDate * converti = [[NSCalendar currentCalendar] startOfDayForDate: sender.date];' – vadian

+0

@Rob Mais je l'ai mis en place UTC pour objet DateComponents. Donc, je m'attendrais à ce que la valeur UTC soit sortie dans le journal. –

Répondre

1

Cela dépend de votre intention. Considérez:

NSString *string = @"1963-02-23 12:00:00 am +0000"; 
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
formatter.dateFormat = @"yyyy-MM-dd hh:mm:ss a X"; 
NSDate *date = [formatter dateFromString:string]; 
NSCalendar *calendar = [NSCalendar currentCalendar]; 
calendar.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; 
NSDateComponents *comps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date]; 
NSLog(@"%@", comps); 

Cela compte:

< NSDateComponents: 0x610000140420 >
Année civile: 1963
Mois: 2
mois Leap: pas
jour: 23

Je peux ensuite convertir en une date dans notre fuseau horaire local avec:

NSDate *converted = [[NSCalendar currentCalendar] dateFromComponents:comps]; 
NSLog(@"%@", converted); 

Cela montrera que minuit dans mon fuseau horaire local (GMT-8), qui est 8 heures GMT:

1963-02-23 08:00:00 +0000

Mais quand j'utilise un formatter pour montrer ce à l'utilisateur, cependant, il montre que pour moi dans mon fuseau horaire local:

NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init]; 
outputFormatter.dateStyle = NSDateFormatterMediumStyle; 
outputFormatter.timeStyle = NSDateFormatterMediumStyle; 
NSLog(@"%@", [outputFormatter stringFromDate:converted]); 

Cela montrera:

23 Feb 1963 00:00:00

De toute évidence, utilisez timeStyle de NSDateFormatterNoStyle si vous ne voulez pas montrer le temps, mais je inclus juste pour vous montrer ce qui se passait vraiment.

Personnellement, je trouve tout ce qui précède assez alambiquée. Je devine que la chaîne originale essayait de refléter une date indépendante de n'importe quel temps et/ou fuseau horaire particulier (par exemple un anniversaire, un anniversaire, etc.), alors je pense que tout est beaucoup plus facile si vous omettez l'heure et le fuseau horaire informations de la chaîne d'origine et juste capturer la date au format yyyy-MM-dd et laissez-le à cela. Alors cela simplifie une grande partie du code ci-dessus.

Je pourrait suggérer de clarifier votre intention réelle, pourquoi vous faites ce que vous faites, et nous pourrions être en mesure d'offrir un meilleur conseil.

+0

Vous êtes un héros. Merci beaucoup. –