2013-10-04 65 views
2

我有這兩個NSDate S:NSPredicate兩個日期之間的範圍沒有按預期工作

NSDateFormatter *df = [[NSDateFormatter alloc] init]; 
[df setDateFormat:@"MM/dd/yyyy"]; 
NSDate *rangeStart = [df dateFromString: @"03/03/2013"]; 
NSDate *rangeEnd = [df dateFromString: @"10/04/2013"]; 

而這個斷言:

request.predicate = [NSPredicate predicateWithFormat:@"createdDate >= %@ AND createdDate <= %@", rangeStart, rangeEnd]; 

但是,即使謂語的第二部分專門使用一直到前一天(即10/03/2013)才返回對象。

我也嘗試構建謂詞是這樣的:

NSPredicate *dateStartPredicate = [NSPredicate predicateWithFormat:@"createdDate >= %@", rangeStart]; 
NSPredicate *dateEndPredicate = [NSPredicate predicateWithFormat:@"createdDate <= %@", rangeEnd]; 
NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:dateStartPredicate, dateEndPredicate, nil]]; 

但我得到了相同的結果。難道我做錯了什麼?這實際上是預期的行爲?如果是,如何設置rangeEnd到第二天?

由於

回答

4

NSDate對象包括時間爲好。當您沒有時間將日期傳遞給dateFromString:方法時,假定相應日的午夜,即只有在午夜發生的項纔會以小於或等於表達式返回true

有解決它的兩種常用方法:

  • 添加一天rangeEnd,並使用「小於」,而不是「小於或等於」,或
  • 添加時間到rangeEnd日期(這並不理想,因爲您需要以長字符串指定時間,或者錯過當天最後一秒發生的項目)。

這裏是如何使用第一種方法:

request.predicate = [NSPredicate 
    predicateWithFormat:@"createdDate >= %@ AND createdDate < %@" 
    , rangeStart 
    , [rangeEnd dateByAddingTimeInterval:60*60*24] 
]; 
+0

感謝您的描述,不知道這一點。但是你看到我的問題結束了嗎? 「如果是的話,怎麼能把距離設置到第二天?」你能詳細說明一下嗎?謝謝 – Jan

+0

@Jan當然,看看編輯。 – dasblinkenlight

2

請記住,即使類的名稱是NSDate的,這些對象表示在時間(而不是整個天)的特定點。 rangeEnd定於10月4日午夜。由於午夜是當天的第一個時刻,因此只有當天午夜的事件纔會包含在您的結果中。如下圖所示,將rangeEnd移動到第二天,您應該可以得到您期望的結果。

NSCalendar* calendar = [NSCalendar autoupdatingCurrentCalendar]; 
NSDateComponents* components = [[NSDateComponents alloc] init]; 
components.day = 1; 
NSDate* newDate = [calendar dateByAddingComponents:components toDate:rangeEnd options: 0]; 
+0

感謝您的描述,不知道這一點。但是你看到我的問題結束了嗎? 「如果是的話,怎麼能把距離設置到第二天?」你能詳細說明一下嗎?謝謝 – Jan

+1

@Jan這個方法考慮了閏秒以及一天中可能不一定等於24 * 60 * 60秒的各種事情。 –

+0

非常感謝。我最終使用@dasblinkenlight答案因爲簡單,他首先回答。不過,我確實收到了答案。謝謝! – Jan

相關問題