2009-10-22 68 views
4

我已經從核心數據加載項目在NSMutableArray。每個項目創建時都會給出一個截止日期,即用戶的選擇。NSDate今天排序NSArray

如何排序,所以只顯示今天到期的項目?

這是我走到這一步:

NSPredicate *predicate = [NSPredicate predicateWithFormat: @"dueDate == %@", [NSDate date]]; 

[allObjectsArray filterUsingPredicate: predicate]; 

此代碼不工作,但是。

感謝您的任何建議

回答

0

方法-filterUsingPredicate:僅適用於可變陣列(的NSMutableArray類型)。

嘗試使用-filteredArrayUsingPredicate:方法,而不是:

NSString *formattedPredicateString = [NSString stringWithFormat:@"dueDate == '%@'", [NSDate date]]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:formattedPredicateString]; 
NSArray *filteredArray = [allObjectsArray filteredArrayUsingPredicate:predicate]; 
1

使用謂詞的問題是,如果他們使用標準的日期比較,它只會返回日期是準確的日期時間的給定日期。如果你想「今天」的日期,你需要的地方增加一個-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! 
+0

這種方法可行,但它需要大量的日期處理和每個項目的計算。所以如果有幾百個項目(或更多),那麼處理時間會開始累加。 –

+0

最重要的是,需要注意以下幾項: http://www.mikeabdullah.net/NSCalendar_currentCalendar.html –

12

你怎麼樣纔算今天在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! 
+5

+1這可能是您的最佳選擇。 '> && <'的替代方法是使用'BETWEEN'關鍵字:'NSPredicate * predicate = [NSPredicate predicateWithFormat:@「dueDate BETWEEN%@」,[NSArray arrayWithObjects:fromDate,toDate,nil]];'您在使用'predicateWithFormat:'時不必構造'predicateString'對象) –

+0

感謝+1!是的,我想過使用'BETWEEN'關鍵字,但是由於toDate是午夜的第二天,所以我希望謂詞小於但不等於該日期。如果我沒有記錯,「BETWEEN」包含上限和下限。關於'predicateWithFormat:'你也是非常正確的! –