iOS: сравните два NSDate-ов без временной доли - PullRequest
27 голосов
/ 06 июня 2011

Я хочу сравнить две даты: date1 и date2

2011-06-06 12:59:48.994 Project[419:707] firstDate:2011-06-06 10:59:21 +0000
2011-06-06 12:59:49.004 Project[419:707] selectedData:2011-06-06 10:59:17 +0000

, но эти даты имеют разное время, и когда я использую NSOrderedSame, он не работает нормально, как мне решить?* мой код:

NSDate *firstDate = [[appDelegate.project objectAtIndex:i]objectAtIndex:3];
NSDate *secondDate = [[appDelegate.project objectAtIndex:i]objectAtIndex:4];

NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger comps = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);

NSDateComponents *date1Components = [calendar components:comps 
                                                            fromDate:firstDate];
NSDateComponents *date2Components = [calendar components:comps 
                                                            fromDate:secondDate];
NSDateComponents *date3Components = [calendar components:comps fromDate:appDelegate.selectedDate];

NSLog(@"firstDate:%@", [date1Components date]);
NSLog(@"secondDate:%@", [date2Components date]);
NSLog(@"selectedData:%@", [date3Components date]);

NSComparisonResult compareStart = [[date1Components date] compare: [date3Components date]]; 
NSComparisonResult compareEnd = [[date2Components date] compare: [date3Components date]]; 

if ((compareStart == NSOrderedAscending || compareStart == NSOrderedSame)
     && (compareEnd == NSOrderedDescending || compareEnd == NSOrderedSame))

{
    NSLog(@"inside");

Затем я хочу сравнить свои даты и записи внутри «если», когда date1 <= selectedDate <= date2;теперь я понимаю, потому что у меня есть предупреждение: я должен добавить это "[date1Components date]", и это работает;проблема в том, что у меня в NSLog нулевые значения, почему ?? </p>

Ответы [ 4 ]

52 голосов
/ 06 июня 2011
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger comps = (NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear);

NSDateComponents *date1Components = [calendar components:comps 
                                                fromDate: date1];
NSDateComponents *date2Components = [calendar components:comps 
                                                fromDate: date2];

date1 = [calendar dateFromComponents:date1Components];
date2 = [calendar dateFromComponents:date2Components];

NSComparisonResult result = [date1 compare:date2];
if (result == NSOrderedAscending) {
} else if (result == NSOrderedDescending) {
}  else {
    //the same
}

Существует еще один удобный метод для создания для данной даты даты, которая представляет начало данной единицы: [aCalendar rangeOfUnit:startDate:interval:forDate:]
Чтобы проиллюстрировать, как работает этот метод, посмотрите этот код, который легко создает дату начала дня, недели, месяца и года для данной даты (здесь: сейчас).

NSDate *now = [NSDate date];
NSDate *startOfToday = nil;
NSDate *startOfThisWeek = nil;
NSDate *startOfThisMonth = nil;
NSDate *startOfThisYear = nil;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startOfToday interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startOfThisWeek interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startOfThisMonth interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startOfThisYear interval:NULL forDate:now];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];

NSLog(@"%@", [formatter stringFromDate:now]);
NSLog(@"%@", [formatter stringFromDate:startOfToday]);
NSLog(@"%@", [formatter stringFromDate:startOfThisWeek]);
NSLog(@"%@", [formatter stringFromDate:startOfThisMonth]);
NSLog(@"%@", [formatter stringFromDate:startOfThisYear]);

результат:

Thursday, July 12, 2012, 4:36:07 PM Central European Summer Time 
Thursday, July 12, 2012, 12:00:00 AM Central European Summer Time 
Sunday, July 8, 2012, 12:00:00 AM Central European Summer Time 
Sunday, July 1, 2012, 12:00:00 AM Central European Summer Time 
Sunday, January 1, 2012, 12:00:00 AM Central European Standard Time

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

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

NSComparisonResult result = [date1 compare:date2];
if (result == NSOrderedAscending) {
} else if (result == NSOrderedDescending) {
}  else {
    //the same
}

Обратите внимание, что в этом коде date1 и date2 будут перезаписаны. В качестве альтернативы вы можете передать ссылку на другой указатель NSDate для startDate, как показано в коде выше, где now остается нетронутым.

27 голосов
/ 27 сентября 2013

Я использовал другой метод с NSDateFormatter и сравнение строк, менее умный, чем NSDate метод сравнения , но более быстрый для написания и достаточно гибкий, чтобы выполнять различные сравнения:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd"];

if ([[dateFormat stringFromDate:date1] isEqualToString:[dateFormat stringFromDate:date2]])
{
    //It's the same day
}
6 голосов
/ 11 ноября 2016

Хорошо, прошло несколько лет после того, как был задан исходный вопрос, но, вероятно, стоит упомянуть, что NSCalendar теперь имеет ряд методов, которые делают некоторые вопросы сравнения дат намного более простыми:

NSCalendar *currentCalendar = [NSCalendar currentCalendar];
Bool sameDay = [currentCalendar isDate:dateA inSameDayAsDate:dateB];
2 голосов
/ 30 августа 2016

Swift Version , сравнение дат и игнорирование их времени.

let dateExam1:NSDate = NSDate.init(timeIntervalSinceNow: 300)
let dateExam2:NSDate = NSDate.init(timeIntervalSinceNow: 10000)

let currCalendar = NSCalendar.currentCalendar()

let dateCompanent1:NSDateComponents = currCalendar.components([.Year,.Month,.Day], fromDate: dateExam1)
let dateCompanent2:NSDateComponents = currCalendar.components([.Year,.Month,.Day], fromDate: dateExam2)

let date1WithoutTime:NSDate? = currCalendar .dateFromComponents(dateCompanent1)
let date2WithoutTime:NSDate? = currCalendar .dateFromComponents(dateCompanent2)
if (date1WithoutTime != nil) && (date2WithoutTime != nil)
{
    let dateCompResult:NSComparisonResult = date1WithoutTime!.compare(date2WithoutTime!)
    if (dateCompResult == NSComparisonResult.OrderedSame)
    {
        print("Same Dates")
    }
    else
    {
        print("Different Dates")
    }
}
...