IOS: сравнить два NSDate-s без временной части
Я хочу сравнить две даты: 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");
Затем я хочу сравнить свои даты и запись внутри "if", когда date1 <= selectedDate <= date2; теперь я понимаю, потому что у меня есть предупреждение: я должен добавить это "[date1Components date]", и он работает; проблема в том, что у меня есть нулевые значения NSLog, почему?
Ответы
Ответ 1
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
остается нетронутым.
Ответ 2
Я использовал другой метод с NSDateFormatter и сравнение строк, менее умное, чем
NSDate сравнить метод, но быстрее писать и достаточно гибко, чтобы сделать разнообразие сравнения:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd"];
if ([[dateFormat stringFromDate:date1] isEqualToString:[dateFormat stringFromDate:date2]])
{
//It the same day
}
Ответ 3
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")
}
}
Ответ 4
Хорошо, так что через несколько лет после того, как был задан исходный вопрос, но, вероятно, стоит упомянуть, что NSCalendar
теперь имеет номер методов, которые делают вопросы сопоставления даты намного более прямолинейными:
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
Bool sameDay = [currentCalendar isDate:dateA inSameDayAsDate:dateB];