web-dev-qa-db-fra.com

Comment comparer deux NSDates: lequel est le plus récent?

J'essaie de réaliser une synchronisation dropBox et je dois comparer les dates de deux fichiers. L'un se trouve sur mon compte dropBox et l'autre sur mon iPhone. 

Je suis venu avec ce qui suit, mais j'obtiens des résultats inattendus. Je suppose que je fais quelque chose de fondamentalement faux en comparant les deux dates. J'ai simplement utilisé les opérateurs> <, mais je suppose que ce n'est pas bon, car je compare deux chaînes NSDate. Et c'est parti:

NSLog(@"dB...lastModified: %@", dbObject.lastModifiedDate); 
NSLog(@"iP...lastModified: %@", [self getDateOfLocalFile:@"NoteBook.txt"]);

if ([dbObject lastModifiedDate] < [self getDateOfLocalFile:@"NoteBook.txt"]) {
    NSLog(@"...db is more up-to-date. Download in progress...");
    [self DBdownload:@"NoteBook.txt"];
    NSLog(@"Download complete.");
} else {
    NSLog(@"...iP is more up-to-date. Upload in progress...");
    [self DBupload:@"NoteBook.txt"];
    NSLog(@"Upload complete.");
}

Cela m'a donné la sortie suivante (aléatoire et erronée):

2011-05-11 14:20:54.413 NotePage[6918:207] dB...lastModified: 2011-05-11 13:18:25 +0000
2011-05-11 14:20:54.414 NotePage[6918:207] iP...lastModified: 2011-05-11 13:20:48 +0000
2011-05-11 14:20:54.415 NotePage[6918:207] ...db is more up-to-date.

ou celui qui se trouve être correct:

2011-05-11 14:20:25.097 NotePage[6903:207] dB...lastModified: 2011-05-11 13:18:25 +0000
2011-05-11 14:20:25.098 NotePage[6903:207] iP...lastModified: 2011-05-11 13:19:45 +0000
2011-05-11 14:20:25.099 NotePage[6903:207] ...iP is more up-to-date.
237
n.evermind

Supposons deux dates:

NSDate *date1;
NSDate *date2;

Ensuite, la comparaison suivante indiquera lequel est antérieur/ultérieur/identique:

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

Veuillez vous reporter à la documentation de la classe NSDate pour plus de détails.

641
Nick Weaver

En retard pour la fête, mais un autre moyen simple de comparer des objets NSDate consiste à les convertir en types primitifs, ce qui facilite l'utilisation de '>' '<' '=='

par exemple.

if ([dateA timeIntervalSinceReferenceDate] > [dateB timeIntervalSinceReferenceDate]) {
    //do stuff
}

timeIntervalSinceReferenceDate convertit la date en secondes depuis la date de référence (1er janvier 2001, GMT). Comme timeIntervalSinceReferenceDate renvoie un NSTimeInterval (qui est un double typedef), nous pouvons utiliser des comparateurs primitifs.

47
So Over It

Dans Swift, vous pouvez surcharger les opérateurs existants:

func > (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.timeIntervalSinceReferenceDate > rhs.timeIntervalSinceReferenceDate
}

func < (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.timeIntervalSinceReferenceDate < rhs.timeIntervalSinceReferenceDate
}

Ensuite, vous pouvez comparer directement les dates NSD avec <, > et == (déjà pris en charge).

14
Andrew

NSDate a une fonction de comparaison.

compare: Renvoie une valeur NSComparisonResult qui indique l'ordre temporel du destinataire 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 nil, le comportement n'est pas défini et pourrait changer dans les futures versions de Mac OS X.

Valeur de retour:

  • Si le destinataire et anotherDate sont exactement égaux, NSOrderedSame
  • Si le destinataire est plus tard que anotherDate, NSOrderedDescending
  • Si le destinataire est plus tôt que anotherDate, NSOrderedAscending.
13
Gary

Vous souhaitez utiliser les méthodes NSDate compare: later: laterDate:, earlyDate: ou isEqualToDate: Utiliser les opérateurs <et> dans cette situation, c'est comparer les pointeurs, pas les dates

12
Dan F
- (NSDate *)earlierDate:(NSDate *)anotherDate

Ceci retourne le plus tôt du destinataire et anotherDate. Si les deux sont identiques, le destinataire est renvoyé.

11
user745098

Certains utilitaires de date, y compris les comparaisons en anglais, qui est Nice

#import <Foundation/Foundation.h>


@interface NSDate (Util)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
- (NSDate*) dateByAddingDays:(int)days;

@end

La mise en oeuvre:

#import "NSDate+Util.h"


@implementation NSDate (Util)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedAscending);
}

-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedDescending);

}
-(BOOL) isEarlierThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedAscending);
}

- (NSDate *) dateByAddingDays:(int)days {
    NSDate *retVal;
    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setDay:days];

    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    retVal = [gregorian dateByAddingComponents:components toDate:self options:0];
    return retVal;
}

@end
7
Dan Rosenstark

Tu devrais utiliser :

- (NSComparisonResult)compare:(NSDate *)anotherDate

comparer les dates. Il n'y a pas de surcharge de l'opérateur dans l'Objectif C.

6
Joris Mans

Pourquoi n'utilisez-vous pas ces méthodes de comparaison NSDate:

- (NSDate *)earlierDate:(NSDate *)anotherDate;
- (NSDate *)laterDate:(NSDate *)anotherDate;
5
justicepenny

J'ai rencontré presque la même situation, mais dans mon cas, je vérifie si la différence de nombre de jours

NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *compDate = [cal components:NSDayCalendarUnit fromDate:fDate toDate:tDate options:0];
int numbersOfDaysDiff = [compDate day]+1; // do what ever comparison logic with this int.

Utile lorsque vous devez comparer NSDate en unité Jours/Mois/Année 

4
Andy

Vous pouvez aussi comparer deux dates avec cette méthode

        switch ([currenttimestr  compare:endtimestr])
        {
            case NSOrderedAscending:

                // dateOne is earlier in time than dateTwo
                break;

            case NSOrderedSame:

                // The dates are the same
                break;
            case NSOrderedDescending:

                // dateOne is later in time than dateTwo


                break;

        }
1
kapil

Je l'ai essayé en espérant que cela fonctionne pour vous 

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];      
int unitFlags =NSDayCalendarUnit;      
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];     
NSDate *myDate; //= [[NSDate alloc] init];     
[dateFormatter setDateFormat:@"dd-MM-yyyy"];   
myDate = [dateFormatter dateFromString:self.strPrevioisDate];     
NSDateComponents *comps = [gregorian components:unitFlags fromDate:myDate toDate:[NSDate date] options:0];   
NSInteger day=[comps day];
0
Concept Infoway

Utilisez cette fonction simple pour comparer les dates

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

BOOL isTokonValid;

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

return isTokonValid;}
0
Akhtar