iOS:比较两个没有时间部分的NSDate-s

Cra*_*Dev 27 cocoa-touch objective-c nsdate ios

我想比较两个日期: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
Run Code Online (Sandbox Code Playgroud)

但这些日期有不同的时间,当我使用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");
Run Code Online (Sandbox Code Playgroud)

然后我想在date1 <= selectedDate <= date2时比较"if"中的日期和条目; 现在我理解,因为我有一个警告:我应该添加这个"[date1Components date]"并且它有效; 问题是我在NSLog中有空值,为什么?

Vik*_*ica 52

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
}
Run Code Online (Sandbox Code Playgroud)

还有另一种方便的方法可以为给定日期创建表示给定单位开头的日期: 要说明此方法的工作原理,请参阅此代码,该代码可轻松创建日,周,月和年的开头日期对于给定的日期(这里:现在).[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]);
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

这允许我们将第一个代码缩短为:

[[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
}
Run Code Online (Sandbox Code Playgroud)

请注意,在这段代码,date1并且date2将被覆盖.或者,您可以传入对另一个NSDate指针的引用,startDate如上面的代码所示,其中now保持不变.


小智 27

我使用了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
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*son 6

好的,所以这是在提出原始问题几年之后,但值得一提的是,NSCalendar现在有许多方法可以使某些日期比较问题更直接:

NSCalendar *currentCalendar = [NSCalendar currentCalendar];
Bool sameDay = [currentCalendar isDate:dateA inSameDayAsDate:dateB];
Run Code Online (Sandbox Code Playgroud)