2013-04-05 203 views
12

我試圖獲取匹配用戶selectedDate(它是一個NSDate)的實體中的所有對象。 核心數據代碼很好,但是我的謂詞一直返回0個結果,日期在用戶選擇的數據庫中是一樣的。核心數據謂詞日期比較

如何將selectedDate與來自使用謂詞的實體的日期進行比較?

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eDate = %@)", selectedDate]; 

回答

22

你的謂詞看起來沒問題。

您找到零結果的原因可能會返回,但可能是日期不完全相同。

例如:

05/04/2012 13:37:00不會與05/04/2012 13:37:01匹配因爲這兩個值不完全相同。

是否要檢查日期(日,月,年)以及時間?

如果您只想檢查日期,您應該創建開始日期和結束日期,並使用用戶選擇的日期作爲參考框架進行比較。

與此類似的東西應該爲00:00:00創建一個日期和時間。

//gather current calendar 
NSCalendar *calendar = [NSCalendar currentCalendar]; 

//gather date components from date 
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; 

//set date components 
[dateComponents setHour:0]; 
[dateComponents setMinute:0]; 
[dateComponents setSecond:0]; 

//return date relative from date 
return [calendar dateFromComponents:dateComponents]; 

由小時,分鐘和秒設置爲23:59:59創建另一個日期,並檢查您的用戶選擇的日期落在這些範圍之間。

[NSPredicate predicateWithFormat:@"date BETWEEN %@", [NSArray arrayWithObjects:startOfDay, endOfDay, nil]] 
+7

它的工作原理,謝謝。通過在謂詞中使用數組,我得到了一個錯誤,但這工作..... @「eDate>%@ AND eDate <%@」,date1,date2]再次感謝。 – user2228755 2013-04-05 11:39:18

+0

爲什麼要添加'NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit'在'components:fromDate:'只是爲了拋棄它? – vikingosegundo 2013-04-05 13:31:25

+0

我的不好。這是我從一個實際使用這些組件的項目中粘貼的代碼。爲了本文的目的,我忽略了刪除它們。我會立即修改;]謝謝指出! – CaptainRedmuff 2013-04-05 13:43:45

11

雖然在人類交流日期通常與日等同,但與NSDate對象不同:NSDate表示單個時刻。幾秒鐘內不同的日期不相等。實際上,它們根本不代表日,月,年,因爲這與日曆系統到日曆系統的日曆系統不同

您必須爲自己定義同一分鐘,小時,日期中的日期是否相等。所以基本上你必須教程序允許一些模糊性。

這裏分鐘分辨率

NSDate *startDate = ....; 
NSTimeInterval length; 

[[NSCalendar currentCalendar] rangeOfUnit:NSMinuteCalendarUnit 
           startDate:&startDate 
           interval:&length 
            forDate:startDate]; 

NSDate *endDate = [startDate dateByAddingTimeInterval:length]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eDate >= %@) AND (eDate < %@)", startDate, endDate]; 

有關的同一天(知道時區和夏令時間)的日期,你只是會改變這一點:

[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit 
           startDate:&startDate 
           interval:&length 
            forDate:startDate]; 
+1

明白了,謝謝您的回答。 – user2228755 2013-04-05 11:40:47

+1

在我看來,這比接受的答案要好得多,因爲它記錄了不同的日曆,並且不會硬編碼當天的開始和停止時間。 – SwampThingTom 2015-01-31 18:48:44

0

最近,我花了一些時間試圖解決這個問題,並已解決以下問題,現在更新爲iOS 8及以上...

NSDate *dateDay = nil; 
NSDate *dateDayStart = nil; 
NSDate *dateDayNext = nil; 

dateDay = <<USER_INPUT>>; //for example - selectedDate 

dateDayStart = [[NSCalendar currentCalendar] startOfDayForDate:dateDay]; 

// dateDayNext EITHER 
dateDayNext = [dateDayStart dateByAddingTimeInterval:(24 * 60 * 60)]; 

// dateDayNext OR 
NSDateComponents *dateComponentDay = nil; 
dateComponentDay = [[NSDateComponents alloc] init]; 
[dateComponentDay setDay:1]; 
dateDayNext = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponentDay 
                  toDate:dateDayStart 
                  options:NSCalendarMatchNextTime]; 

...和NSPredicate的核心數據NSFetchRequest(如已經在其他的答案如上所示)...

[NSPredicate predicateWithFormat:@"(dateAttribute >= %@) AND (dateAttribute < %@)", dateDayStart, dateDayNext]] 
2

我可以得到一些修改,以接受的答案工作,並使用用於iOS的API 8用時間偏移創建日期。代碼:

NSCalendar *calendar = [[FFSharedCalendar singleton] getGregorianCalendar]; 
NSDate *startOfDay = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0]; 
NSDate *endOfDay = [calendar dateBySettingHour:23 minute:59 second:59 ofDate:[NSDate date] options:0]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"createdAt > %@ AND createdAt < %@", startOfDay, endOfDay]; 
NSArray* plans = [Plan MR_findAllWithPredicate:predicate]; 

希望它可以幫助別人

+1

這對我來說就像魅力... upvoted! – NSPratik 2016-09-29 05:35:57