今天按 NSDate 对 NSArray 进行排序
Posted
技术标签:
【中文标题】今天按 NSDate 对 NSArray 进行排序【英文标题】:Sort NSArray by NSDate, today 【发布时间】:2009-10-22 08:42:48 【问题描述】:我已从 NSMutableArray 中的核心数据加载项目。每个项目在创建时都有一个截止日期,用户可以选择该截止日期。
如何排序,只显示今天到期的项目?
这是我目前得到的:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"dueDate == %@", [NSDate date]];
[allObjectsArray filterUsingPredicate: predicate];
但是,此代码不起作用。
感谢您的任何建议
【问题讨论】:
【参考方案1】:您可以先计算今天的 00:00,然后计算明天的 00:00,然后将谓词中的日期与那些日期(>= 和
// Setup
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
// Get todays year month and day, ignoring the time
NSDateComponents *comp = [cal components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:now];
// Components to add 1 day
NSDateComponents *oneDay = [[NSDateComponents alloc] init];
oneDay.day = 1;
// From date & To date
NSDate *fromDate = [cal dateFromComponents:comp]; // Today at midnight
NSDate *toDate = [cal dateByAddingComponents:oneDay toDate:fromDate options:0]; // Tomorrow at midnight
// Cleanup
[oneDay release]
// Filter Mutable Array to Today
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"dueDate >= %@ && dueDate < %@", fromDate, toDate];
NSArray *filteredArray = [allObjectsArray filteredArrayUsingPredicate:predicate];
// Job Done!
【讨论】:
+1 这可能是您的最佳选择。>= && <
的替代方法是使用BETWEEN
关键字:NSPredicate * predicate = [NSPredicate predicateWithFormat:@"dueDate BETWEEN %@", [NSArray arrayWithObjects:fromDate, toDate, nil]];
(请注意,使用predicateWithFormat:
时不必构造predicateString
对象)
感谢您的 +1!是的,我考虑过使用 BETWEEN
关键字,但是由于 toDate 是第二天午夜,所以我希望谓词小于但不等于该日期。如果我没记错的话,BETWEEN
包括上限和下限。另外,predicateWithFormat:
!【参考方案2】:
使用谓词的问题在于,如果它们使用标准日期比较,它只会返回与给定日期的日期和时间完全相同的日期。如果您想要“今天”日期,则需要在某处添加 -isToday 方法(可能作为 NSDate 的扩展),如下所示:
-(BOOL)dateIsToday:(NSDate *)aDate
NSDate *now = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *nowComponents = [cal components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit
fromDate:now];
NSDateComponents *dateComponents = [cal components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit
fromDate:aDate];
return (([nowComponents day] == [dateComponents day]) &&
([nowComponents month] == [dateComponents month]) &&
([nowComponents year] == [dateComponents year]));
一旦你有了它,就很容易找到今天的那些:
NSMutableArray *itemsDueToday = [NSMutableArray array];
for (MyItem *item in items)
if ([self dateIsToday:[item date])
[itemsDueToday addObject:item];
// Done!
【讨论】:
这种方法可行,但是它需要对每个项目进行大量的日期处理和计算。因此,如果有几百个(或更多)项目,那么处理时间就会开始增加。 除此之外,还有额外的费用需要注意:mikeabdullah.net/NSCalendar_currentCalendar.html【参考方案3】:-filterUsingPredicate:
方法仅适用于可变数组(NSMutableArray
类型)。
尝试改用-filteredArrayUsingPredicate:
方法:
NSString *formattedPredicateString = [NSString stringWithFormat:@"dueDate == '%@'", [NSDate date]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:formattedPredicateString];
NSArray *filteredArray = [allObjectsArray filteredArrayUsingPredicate:predicate];
【讨论】:
以上是关于今天按 NSDate 对 NSArray 进行排序的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 NSDate 属性对 NSMangedObjects 进行排序
如何按日期降序对 NSDate 进行排序,但在该日期内时间升序?
如何按数组计数对嵌套 NSArray 的 NSArray 进行排序?