Sort NSArray by NSDate, today
I have loaded item from core data in an NSMutableArray. Each item, when created, is given a due date, that the user choices.
How do I sort,开发者_如何学C so only the item that is due today is displayed?
Here is what I got so far:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"dueDate == %@", [NSDate date]];
[allObjectsArray filterUsingPredicate: predicate];
This code doesn't work however.
Thanks for any suggestions
How about you just calculate today at 00:00 and then tomorrow at 00:00 and then compare the dates in the predicate to those (>= and <). So all date objects must be within those two dates to be classed as being 'Today'. This requires you to only calculate 2 dates initially, no matter how many date objects are in your array.
// 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!
The problem with using predicates is that if they use standard date comparison, it'll only return dates that are exactly the date and time of the given date. If you want "today" dates, you'll need to add a -isToday method somewhere (possible as an extension to NSDate), like this:
-(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]));
}
Once you have that, it's simple enough to find the ones that are today:
NSMutableArray *itemsDueToday = [NSMutableArray array];
for (MyItem *item in items) {
if ([self dateIsToday:[item date]) {
[itemsDueToday addObject:item];
}
}
// Done!
The method -filterUsingPredicate:
only works on mutable arrays (of type NSMutableArray
).
Try using the -filteredArrayUsingPredicate:
method, instead:
NSString *formattedPredicateString = [NSString stringWithFormat:@"dueDate == '%@'", [NSDate date]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:formattedPredicateString];
NSArray *filteredArray = [allObjectsArray filteredArrayUsingPredicate:predicate];
精彩评论