Как сравнить два NSDates: что является более поздним? - PullRequest
238 голосов
/ 11 мая 2011

Я пытаюсь добиться синхронизации dropBox и мне нужно сравнить даты двух файлов. Один на моем аккаунте dropBox, а другой на моем iPhone.

Я придумал следующее, но получил неожиданные результаты. Я думаю, что я делаю что-то в корне неправильно, сравнивая две даты. Я просто использовал операторы> <, но, думаю, это не очень хорошо, так как я сравниваю две строки NSDate. Вот и мы: </p>

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.");
}

Это дало мне следующий (случайный и неправильный) вывод:

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.

или этот, который оказывается правильным:

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.

Ответы [ 13 ]

647 голосов
/ 11 мая 2011

Давайте предположим две даты:

NSDate *date1;
NSDate *date2;

Тогда следующее сравнение скажет, что раньше / позже / то же самое:

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");
}

Пожалуйста, обратитесь к документации класса NSDate для более подробной информации.

48 голосов
/ 07 мая 2013

Поздно к вечеринке, но другой простой способ сравнения объектов NSDate - это преобразование их в примитивные типы, что позволяет легко использовать '>' '<' '==' и т. Д. </p>

например.

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

timeIntervalSinceReferenceDate преобразует дату в секунды после отчетной даты (1 января 2001 года, время по Гринвичу).Поскольку timeIntervalSinceReferenceDate возвращает NSTimeInterval (который является двойной типовой дефиницией), мы можем использовать примитивные компараторы.

14 голосов
/ 08 декабря 2014

В Swift вы можете перегрузить существующие операторы:

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

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

Затем вы можете сравнить NSDates напрямую с <, > и == (уже поддерживается).

13 голосов
/ 11 мая 2011

NSDate имеет функцию сравнения.

compare: Возвращает значение NSComparisonResult, которое указывает временное упорядочение получателя и другую заданную дату.

(NSComparisonResult)compare:(NSDate *)anotherDate

Параметры : anotherDate Дата, с которой сравнивается получатель.Это значение не должно быть равно нулю.Если значение равно nil, поведение не определено и может измениться в будущих версиях Mac OS X.

Возвращаемое значение:

  • Если получатель и anotherDateточно равны друг другу, NSOrderedSame
  • Если получатель позже по времени, чем другая дата, NSOrderedDescending
  • Если получатель раньше по времени, чем другая дата, NSOrderedAscending.
12 голосов
/ 11 мая 2011

Вы хотите использовать методы сравнения NSDate :, LaterDate :, earlyDate: или isEqualToDate:.Использование операторов <и> в этой ситуации сравнивает указатели, а не даты

11 голосов
/ 11 мая 2011
- (NSDate *)earlierDate:(NSDate *)anotherDate

Возвращает более раннюю версию получателя и другую дату.Если оба одинаковы, получатель возвращается.

7 голосов
/ 08 мая 2014

Некоторые утилиты даты, включая сравнения на АНГЛИЙСКОМ, что приятно:

#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

Реализация:

#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
6 голосов
/ 19 сентября 2014

Почему бы вам, ребята, не использовать эти NSDate методы сравнения:

- (NSDate *)earlierDate:(NSDate *)anotherDate;
- (NSDate *)laterDate:(NSDate *)anotherDate;
6 голосов
/ 11 мая 2011

Вы должны использовать:

- (NSComparisonResult)compare:(NSDate *)anotherDate

для сравнения дат. В целевом объекте C отсутствует перегрузка оператора.

4 голосов
/ 05 ноября 2012

Я столкнулся с почти такой же ситуацией, но в моем случае я проверяю разницу в количестве дней

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.

Полезно, когда вам нужно сравнить NSDate в единицах Дни / Месяц / Год

...