72 votes

Comparer deux NSDates et ignorer le composant de temps

Quel est le plus efficace/recommandée pour la comparaison de deux NSDates? Je voudrais être en mesure de voir si les deux dates sont sur la même journée, indépendamment de l'heure et ont commencé à écrire un peu de code qui utilise la timeIntervalSinceDate: méthode au sein de la NSDate classe et obtient l'entier de cette valeur divisée par le nombre de secondes dans une journée. Cela semble de longue haleine et je sens que je suis absent quelque chose d'évident.

Le code que j'essaie de résoudre est:

if (!([key compare:todaysDate] == NSOrderedDescending))
{
    todaysDateSection = [eventSectionsArray count] - 1;
}

où clés et todaysDate sont NSDate objets et todaysDate est de créer à l'aide de:

NSDate *todaysDate = [[NSDate alloc] init];

Ce qui concerne

Dave

83voto

Ed Marty Points 24861

Je suis surpris que personne n'a d'autres réponses ont cette option pour obtenir le "début de la journée" date pour les objets:

[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&date1 interval:NULL forDate:date1];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&date2 interval:NULL forDate:date2];

Qui définit date1 et date2 pour le début de leurs jours. S'ils sont égaux, ils sont sur le même jour.

Ou cette option:

int day1 = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:date1];
int day2 = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:date2];

Qui définit day1 et day2 quelque peu arbitraire des valeurs qui peuvent être comparés. S'ils sont égaux, ils sont sur le même jour.

73voto

Gregory Pakosz Points 35546

Vous définissez l'heure dans la date à 00:00:00 avant de faire la comparaison:

 unsigned int flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSCalendar* calendar = [NSCalendar currentCalendar];

NSDateComponents* components = [calendar components:flags fromDate:date];

NSDate* dateOnly = [calendar dateFromComponents:components];

// ... necessary cleanup
 

Ensuite, vous pouvez comparer les valeurs de date. Voir l' aperçu dans la documentation de référence .

10voto

Bms270 Points 400

Ceci est un raccourci de toutes les réponses:

 NSInteger interval = [[[NSCalendar currentCalendar] components: NSDayCalendarUnit
                                                                  fromDate: date1
                                                                    toDate: date2
                                                                   options: 0] day];
    if(interval<0){
       //date1<date2
    }else if (interval>0){
       //date2<date1
    }else{
       //date1=date2
    }
 

6voto

Felixyz Points 10705

J'utilise ce petit util méthode:

-(NSDate*)normalizedDateWithDate:(NSDate*)date
{
   NSDateComponents* components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
                                              fromDate: date];
   return [calendar_ dateFromComponents:components]; // NB calendar_ must be initialized
}

(Vous aurez évidemment besoin d'avoir un ivar appelés calendar_ contenant un NSCalendar.)

Avec cela, il est facile de vérifier si une date est aujourd'hui comme ceci:

[[self normalizeDate:aDate] isEqualToDate:[self normalizeDate:[NSDate date]]];

([NSDate date] renvoie la date et l'heure actuelles.)

Bien sûr, ceci est très similaire à ce que Grégoire suggère. L'inconvénient de cette approche est qu'il a tendance à créer beaucoup de temporaire NSDate objets. Si vous allez traiter un beaucoup de dates, je vous recommande d'utiliser une autre méthode, par exemple en comparant les composants directement, ou de travailler avec NSDateComponents objets au lieu de NSDates.

6voto

jcesarmobile Points 6086

J'ai utilisé l'approche de Duncan C, j'ai corrigé quelques erreurs qu'il a faites

 -(NSInteger) daysBetweenDate:(NSDate *)firstDate andDate:(NSDate *)secondDate { 

    NSCalendar *currentCalendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [currentCalendar components: NSDayCalendarUnit fromDate: firstDate toDate: secondDate options: 0];

    NSInteger days = [components day];

    return days;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X