今天按 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 这可能是您的最佳选择。 &gt;= &amp;&amp; &lt; 的替代方法是使用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 进行排序?

按 2 级深的键值关系对 NSArray 进行排序

如何通过数组对象的 NSDate 日期将 NSArray 拆分为 NSDictionary?

按 NSDictionary 值对 NSArray 进行排序