iOS: comparez deux dates

96

J'ai un NSDateque je dois comparer avec deux autres NSDateet j'essaye avec NSOrderAscendinget NSOrderDescendingmais si ma date est égale à deux autres dates?

Exemple: si j'ai un myDate = 24/05/2011 et deux autres qui sont un = 24/05/2011et deux, 24/05/2011que puis-je utiliser?

faire du vélo
la source
1
Je ne comprends pas complètement votre question, qu'essayez-vous de réaliser?
arclight
la date un et la date deux peuvent être un = 15/05/2011 et deux = 31/05/2011 mais elles doivent aussi être le même jour un = 24/05/2011 et deux = 24/05/2011 alors je dois vérifier si myData est entre la date un et la date deux
cyclingIsBetter
Extrayez simplement l'année, le mois et la date et comparez-les dans cet ordre. S'il y a égalité, comparez le champ suivant.
Himadri Choudhury

Réponses:

210

Selon la documentation Apple deNSDate compare:

Renvoie une valeur NSComparisonResult qui indique l'ordre temporel du récepteur et une autre date donnée.

- (NSComparisonResult)compare:(NSDate *)anotherDate

Paramètres anotherDate

La date à laquelle comparer le récepteur. Cette valeur ne doit pas être nulle. Si la valeur est nulle, le comportement n'est pas défini et peut changer dans les futures versions de Mac OS X.

Valeur de retour

Si:

Le récepteur et une autreDate sont exactement égaux l'un à l'autre, NSOrderedSame

Le récepteur est plus tard qu'une autre date, NSOrderedDescending

Le récepteur est plus tôt qu'une autre date, NSOrderedAscending

En d'autres termes:

if ([date1 compare:date2] == NSOrderedSame) ...

Notez qu'il peut être plus facile dans votre cas particulier de lire et d'écrire ceci:

if ([date2 isEqualToDate:date2]) ...

Consultez la documentation Apple à ce sujet .

Vincent Guerci
la source
mais f ([date1 compare: date2] == NSOrderedSame) vérifie aussi les heures, minutes et secondes et je ne les veux pas
cyclingIsBetter
1
votre question n'était pas claire, désolé, jetez un œil à stackoverflow.com/questions/1889164/3092009#3092009 , vous trouverez la réponse à cela.
Vincent Guerci
Cette réponse est correcte dans les deux sens. Pour contrôler les composants de date que vous comparez, utilisezNSDateComponents
Nazir
32

Après avoir beaucoup recherché stackoverflow et le Web, je dois conclure que la meilleure façon de le faire est la suivante:

- (BOOL)isEndDateIsSmallerThanCurrent:(NSDate *)checkEndDate
{
    NSDate* enddate = checkEndDate;
    NSDate* currentdate = [NSDate date];
    NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
    double secondsInMinute = 60;
    NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;

    if (secondsBetweenDates == 0)
        return YES;
    else if (secondsBetweenDates < 0)
        return YES;
    else
        return NO;
}

Vous pouvez également le modifier en différence d'heures.

Prendre plaisir!


Modifier 1

Si vous souhaitez comparer la date au format jj / MM / aaaa uniquement, vous devez ajouter des lignes ci-dessous entre NSDate* currentdate = [NSDate date];&&NSTimeInterval distance

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd/MM/yyyy"];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]
                          autorelease]];

NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];

currentdate = [dateFormatter dateFromString:stringDate];
Yossi Tsafar
la source
1
Merci, cela fonctionne mieux que comparer ou isEqualToDate
ArdenDev
D'accord. J'ai rencontré des problèmes lors de l'utilisation de compare & isEqualToDate. Bien sûr, il peut s'agir de 2 lignes de code supplémentaires, mais c'est plus fiable.
Coach Roebuck
23

Je suppose que vous demandez quelle est la valeur de retour dans la fonction de comparaison.

Si les dates sont égales, alors retour NSOrderedSame

Si croissant (2ème argument> 1er argument) retourne NSOrderedAscending

Si décroissant (2ème argument <1er argument) retourne NSOrderedDescending

Himadri Choudhury
la source
Bon moyen de penser à monter et à descendre.
David
16

Je ne sais pas exactement si vous avez demandé cela, mais si vous voulez seulement comparer le composant de date d'un NSDate, vous devez utiliser NSCalendar et NSDateComponents pour supprimer le composant de temps.

Quelque chose comme ça devrait fonctionner en tant que catégorie pour NSDate:

- (NSComparisonResult)compareDateOnly:(NSDate *)otherDate {
    NSUInteger dateFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit;
    NSCalendar *gregorianCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    NSDateComponents *selfComponents = [gregorianCalendar components:dateFlags fromDate:self];
    NSDate *selfDateOnly = [gregorianCalendar dateFromComponents:selfComponents];

    NSDateComponents *otherCompents = [gregorianCalendar components:dateFlags fromDate:otherDate];
    NSDate *otherDateOnly = [gregorianCalendar dateFromComponents:otherCompents];
    return [selfDateOnly compare:otherDateOnly];
}
Matthias Bauch
la source
2

NSDatereprésente en fait un intervalle de temps en secondes depuis une date de référence (1er janvier 2000 UTC je pense). En interne, un nombre à virgule flottante double précision est utilisé, de sorte que deux dates arbitraires sont très peu susceptibles de se comparer égales même si elles sont le même jour. Si vous voulez voir si une date particulière tombe un jour particulier, vous devez probablement l'utiliser NSDateComponents. par exemple

NSDateComponents* dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2011];
[dateComponents setMonth: 5];
[dateComponents setDay: 24];
/*
 *  Construct two dates that bracket the day you are checking.  
 *  Use the user's current calendar.  I think this takes care of things like daylight saving time.
 */
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* startOfDate = [calendar dateFromComponents: dateComponents];
NSDateComponents* oneDay = [[NSDateComponents alloc] init];
[oneDay setDay: 1];
NSDate* endOfDate = [calendar dateByAddingComponents: oneDay toDate: startOfDate options: 0];
/*
 *  Compare the date with the start of the day and the end of the day.
 */
NSComparisonResult startCompare = [startOfDate compare: myDate];
NSComparisonResult endCompare = [endOfDate compare: myDate];

if (startCompare != NSOrderedDescending && endCompare == NSOrderedDescending)
{
    // we are on the right date
} 
JeremyP
la source
2

Vérifiez la fonction suivante pour la comparaison de date tout d'abord, créez deux objets NSDate et passez à la fonction: Ajoutez les lignes de code ci-dessous dans viewDidload ou selon votre scénario.

-(void)testDateComaparFunc{

NSString *getTokon_Time1 = @"2016-05-31 03:19:05 +0000";
NSString *getTokon_Time2 = @"2016-05-31 03:18:05 +0000";
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss Z"];
NSDate *tokonExpireDate1=[dateFormatter dateFromString:getTokon_Time1];
NSDate *tokonExpireDate2=[dateFormatter dateFromString:getTokon_Time2];
BOOL isTokonValid = [self dateComparision:tokonExpireDate1 andDate2:tokonExpireDate2];}

voici la fonction

-(BOOL)dateComparision:(NSDate*)date1 andDate2:(NSDate*)date2{

BOOL isTokonValid;

if ([date1 compare:date2] == NSOrderedDescending) {
    //"date1 is later than date2
    isTokonValid = YES;
} else if ([date1 compare:date2] == NSOrderedAscending) {
    //date1 is earlier than date2
    isTokonValid = NO;
} else {
   //dates are the same
    isTokonValid = NO;

}

return isTokonValid;}

Changez simplement la date et testez la fonction ci-dessus :)

Akhtar
la source