2013-04-05 47 views
12

Tôi đang cố gắng tìm nạp tất cả các đối tượng trong một đối tượng khớp với người dùng đã chọnDate (đó là một NSDate). Mã Dữ liệu cốt lõi là tốt nhưng vị từ của tôi tiếp tục trả về 0 kết quả, ngày tháng giống nhau trong cơ sở dữ liệu khi người dùng đang chọn.So sánh ngày so sánh dữ liệu cốt lõi

Giá trị được chọn nên được so sánh như thế nào với một ngày từ một thực thể sử dụng vị từ?

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

Trả lời

22

Vị từ của bạn có vẻ ổn.

Lý do bạn tìm thấy kết quả bằng không được trả lại tuy nhiên có thể là các ngày không hoàn toàn giống nhau.

Ví dụ:

05/04/2012 13:37:00 sẽ không phù hợp với 05/04/2012 13:37:01 như hai giá trị này không phải là hoàn toàn giống nhau.

Bạn có muốn kiểm tra ngày (ngày, tháng, năm) cũng như thời gian không?

Nếu bạn chỉ muốn kiểm tra ngày, bạn nên tạo ngày bắt đầu và ngày kết thúc và so sánh chúng bằng cách sử dụng ngày do người dùng chọn làm khung tham chiếu.

Điều gì đó tương tự như vậy sẽ tạo ngày và giờ cho 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]; 

Tạo một ngày khác bằng cách đặt giờ, phút và giây thành 23:59:59 và kiểm tra ngày người dùng đã chọn nằm giữa các phạm vi này.

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

Nó hoạt động, cảm ơn. Tôi đã nhận được một lỗi bằng cách sử dụng các mảng trong vị ngữ nhưng điều này làm việc ..... @ "eDate>% @ VÀ eDate <% @", date1, date2] Cảm ơn một lần nữa. – user2228755

+0

tại sao bạn thêm 'NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit' trong 'thành phần: fromDate:' chỉ để quăng nó đi? – vikingosegundo

+0

Tệ của tôi. Đây là mã tôi dán từ một dự án thực sự sử dụng các thành phần đó. Tôi đã bỏ qua việc xóa chúng vì mục đích của bài đăng này. Tôi sẽ sửa đổi điều đó ngay bây giờ;] Cảm ơn bạn đã chỉ ra! – CaptainRedmuff

11

Trong ngày giao tiếp của con người thường bằng ngày, nó không giống với đối tượng NSDate: NSDate đại diện cho một khoảnh khắc trong thời gian. Ngày khác nhau chỉ trong vài giây không bằng nhau. Và trên thực tế, chúng không đại diện cho ngày, tháng, năm, vì hệ thống này khác với hệ thống lịch theo lịch

bạn phải xác định cho chính mình nếu ngày trong cùng một phút, giờ, ngày… bằng nhau. Vì vậy, về cơ bản bạn phải dạy chương trình để cho phép một số fuzziness.

đây để giải quyết phút

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]; 

Đối ngày vào cùng một ngày (nhận thức múi giờ và Daylight Saving Times), bạn chỉ có thể thay đổi điều này:

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

OK, cảm ơn câu trả lời của bạn. – user2228755

+1

Theo ý kiến ​​của tôi, điều này là tốt hơn nhiều so với câu trả lời được chấp nhận bởi vì nó chiếm các lịch khác nhau và không mã hóa ngày bắt đầu và thời gian dừng của ngày. – SwampThingTom

0

tôi vừa mới trải qua một thời gian cố gắng giải quyết vấn đề tương tự này và đã giải quyết các vấn đề sau, hiện đã được cập nhật cho iOS 8 trở lên ...

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]; 

... và NSPredicate cho Tập dữ liệu cốt lõi NSFetchRequest (như đã trình bày ở trên trong câu trả lời khác) ...

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

tôi có thể có được làm việc với một số sửa đổi để câu trả lời được chấp nhận và sử dụng API iOS 8 cho tạo ngày tháng với thời gian bù đắp.Mã này:

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]; 

Hy vọng nó sẽ giúp người

+1

Điều này làm việc cho tôi như quyến rũ ... upvoted! – NSPratik