2012-05-24 160 views
1

这是我第一次比较Objective-C中的日期。我一直在网上搜索一段时间,我发现所有的例子都涉及到从字符串构建一个NSDate,所以我决定在这里问一个新问题... 我的问题如下:两个NSDate之间的日期比较

我需要知道如果两个NSDate在同一天,忽略时间。我得到了两个NSArray包含一组日期,并且我需要逐个确定第一个NSArray中的哪一个与第二个数组中的第一个日期相同。

- (void)setActiveDaysColor:(UIColor *)activeDaysColor 
{ 
    for (DayView *actualDay in _days) 
    { 
     NSDate *actualDayDate = [actualDay date]; 

     for (NSDate *activeDayDate in self.dates) 
     { 
      // Comparison code 
      // If both dates are the same, tint actualDay with a different color 
     } 
    } 
} 

先谢谢你,祝你有美好的一天。

Alex。

回答

10

通过省略时间组件创建新日期。并使用的比较方法

例如

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

NSDateComponents *firstComponents = [calendar components:components fromDate:firstDate]; 
NSDateComponents *secondComponents = [calendar components:components fromDate:secondDate]; 

NSDate *date1 = [calendar dateFromComponents:firstComponents]; 
NSDate *date2 = [calendar dateFromComponents:secondComponents]; 

NSComparisonResult result = [date1 compare:date2]; 
if (result == NSOrderedAscending) { 
} else if (result == NSOrderedDescending) { 
} else { 
} 
+0

看看[这个答案去“开始日期”](http://stackoverflow.com/a/1857392/608157),并有点惊讶。 –

+0

........惊讶! – vikingosegundo

1

检查的NSDate d一个ocumentation,这些都是比较日期

  • isEqualToDate
  • 方法
  • earlierDate
  • laterDate
  • 你的情况比较

if([actualDayDate isEqualToDate:activeDayDate]) 
{ 

} 
+0

不,这只会检查他们是否完全相同,而不是同一天。 – borrrden

+0

啊,我的不好。谢谢。我错过了。 – suresh

1

感谢您的答案。 我发现一个更清洁的答案,我的问题在一个完全无关的帖子中回答,但实际上完美的作品。

if ((unsigned int)[actualDayDate timeIntervalSinceDate:activeDayDate]/60/60/24 == 0) 
{ 
    // do Stuff 
} 
+0

请注意,如果用户使用另一个日历而不是公历,此代码可能会失败。日期比较必须在日历内完成。 http://stackoverflow.com/questions/6184824/core-data-under-japanese-calendar-incorrectly-comparing-dates – vikingosegundo

+0

你是对的,我没有想到这一点。谢谢! –

+1

你最好使用我的解决方案。如果你觉得,就像它有太多的代码行一样,请使用方法'compareDateOmmitingTime:' – vikingosegundo

1

而不是你在你的代码中的循环,你可以使用谓词过滤掉今天的所有对象。过滤今天的日期是通过将它与今天的开始和今天的结束进行比较来完成的。

您可以设置任何的NSDate该日期这样的开始(见this answer

NSDate *beginDate = [NSDate date]; 
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginDate interval:NULL forDate:beginDate]; 

然后得到的最后一天,你只需添加一天吧。 不要通过计算秒数来增加天数。这不适用于夏令时!像这样做(见this answer):

NSDateComponents *oneDay = [[NSDateComponents alloc] init]; 
[oneDay setDay:1]; 
// one day after begin date 
NSDate *endDate = [[NSCalendar currentCalendar] dateByAddingComponents:oneDay toDate:beginDate options:0]; 

现在,您已经定义为今天你可以使用NSPredicate让所有的DayViews的新数组谁的日子过滤自己的所有DayViews范围内的两个日期今天,这样的(见this answer):

// filter DayViews to only include those where the day is today 
NSArray *daysThatAreToday = [_days filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", beginDate, endDate]]; 

现在,您可以通过枚举新阵列应用着色颜色的所有DayViews(包含今天DayViews)

[daysThatAreToday enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
    // Set the tint color here... 
}]; 

这,在我看来,是一种清洁但解决您的问题更重要的是正确方式。它清楚地读取并处理夏令时和其他日历,然后格雷戈里。如果您想要将某个星期(或任何其他时间段)的所有DayView着色,它也可以轻松重复使用。

+1

注意在该代码的NSDate上创建一个类别,使用此代码,您将完全删除您的时间组件。如果你仍然需要它,你应该做'NSDate * newStartDateDay = nil; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&newStartDateDay interval:NULL forDate:actualDate];'并比较newStartDate,但使用beginDate。 – vikingosegundo

+0

这就是为什么我为'beginDate'和'endDate'创建了两个用于排序的新变量。你的观点仍然有效,这些变量**将会删除他们的时间组件** –

+0

我只是想指出 - 并非它会导致混淆,突然间所有事件都在00:00开始。 – vikingosegundo

2
-(BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 { 
NSCalendar* calendar = [NSCalendar currentCalendar]; 

unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1]; 
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2]; 

return [comp1 day] == [comp2 day] && 
[comp1 month] == [comp2 month] && 
[comp1 year] == [comp2 year];}