Как сравнить два NSDates: что является более поздним?
Я пытаюсь выполнить синхронизацию dropBox и мне нужно сравнить даты двух файлов. Один из них находится на моей учетной записи dropBox, а один - на моем iPhone.
Я придумал следующее, но получаю неожиданные результаты. Наверное, я делаю что-то принципиально неправильное, когда сравниваю две даты. Я просто использовал > < операторов, но я думаю, это нехорошо, поскольку я сравниваю две строки NSDate. Здесь мы идем:
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.
Ответы
Ответ 1
Предположим, что две даты:
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.
Ответ 2
Поздно к партии, но другой простой способ сравнения объектов NSDate состоит в том, чтобы преобразовать их в примитивные типы, что позволяет легко использовать ' > ' '<' '==' и т.д.
например.
if ([dateA timeIntervalSinceReferenceDate] > [dateB timeIntervalSinceReferenceDate]) {
//do stuff
}
timeIntervalSinceReferenceDate
преобразует дату в секундах со ссылочной даты (1 января 2001 года, GMT). Поскольку timeIntervalSinceReferenceDate
возвращает NSTimeInterval (который является двойным typedef), мы можем использовать примитивные компараторы.
Ответ 3
NSDate
имеет функцию сравнения.
compare:
Возвращает значение NSComparisonResult
, которое указывает временное упорядочение получателя и другую заданную дату.
(NSComparisonResult)compare:(NSDate *)anotherDate
Параметры: anotherDate
Дата, с помощью которой можно сравнить приемник.
Это значение не должно быть nil. Если значение равно nil, поведение undefined и может измениться в будущих версиях Mac OS X.
Возвращаемое значение:
- Если получатель и другое значение равно друг другу,
NSOrderedSame
- Если получатель более поздний по времени, чем другой, то
NSOrderedDescending
- Если приемник более раннее по времени, чем anotherDate,
NSOrderedAscending
.
Ответ 4
В Swift вы можете перегрузить существующие операторы:
func > (lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.timeIntervalSinceReferenceDate > rhs.timeIntervalSinceReferenceDate
}
func < (lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.timeIntervalSinceReferenceDate < rhs.timeIntervalSinceReferenceDate
}
Затем вы можете напрямую сравнивать NSDates с <
, >
и ==
(уже поддерживаемыми).
Ответ 5
Вы хотите использовать методы NSDate compare:, laterDate:, earlyDate:, или isEqualToDate:. Используя < и > операторы в этой ситуации сравнивают указатели, а не даты
Ответ 6
- (NSDate *)earlierDate:(NSDate *)anotherDate
Это возвращает ранее получателя и другое значение. Если оба они одинаковы, приемник возвращается.
Ответ 7
Некоторые утилит даты, в том числе сравнения на английском языке, что приятно:
#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
Ответ 8
Вы должны использовать:
- (NSComparisonResult)compare:(NSDate *)anotherDate
сравнить даты. В объекте C нет перегрузки оператора.
Ответ 9
У меня есть почти такая же ситуация, но в моем случае я проверяю, отличается ли разница между днями
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 в единицах дней/месяцев/год
Ответ 10
Почему вы не используете эти методы сравнения NSDate
:
- (NSDate *)earlierDate:(NSDate *)anotherDate;
- (NSDate *)laterDate:(NSDate *)anotherDate;
Ответ 11
Вы можете сравнить две даты этим методом также
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;
}
Ответ 12
Я пробовал надеяться, что он сработает для вас
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];
Ответ 13
Используйте эту простую функцию для сравнения даты
-(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;}