2013-04-05 28 views
12

Próbuję pobrać wszystkie obiekty w elemencie pasującym do wybranej przez użytkownika wartości (jest to NSDate). Kod danych podstawowych jest w porządku, ale mój predykat wraca 0 wyników, daty są takie same w bazie danych, jak użytkownik wybiera.Porównywanie dat danych podstawowych danych

Jak należy porównać wybraną datę z datą z jednostki używającej predykatu?

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

Odpowiedz

22

Twój predykat wygląda dobrze.

Powód znalezienia wyniku zerowego jest zwracany, ale może się zdarzyć, że daty nie są identyczne.

Na przykład:

05/04/2012 13:37:00 nie będzie pasował z 05/04/2012 13:37:01 jak te dwie wartości nie są dokładnie takie same.

Czy chcesz sprawdzić datę (dzień, miesiąc, rok), a także godzinę?

Jeśli chcesz tylko sprawdzić datę, powinieneś utworzyć datę początkową i końcową oraz porównać je z datą wybraną przez użytkownika jako ramką odniesienia.

Coś podobnego do tego powinno stworzyć datę i godzinę 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]; 

Utwórz kolejną datę poprzez ustawienie godziny, minuty i sekundy do 23:59:59 i sprawdzić, czy użytkownik wybrał data przypada pomiędzy tymi zakresami.

+7

To działa, dzięki. Otrzymałem błąd, używając tablicy w predykacie, ale działało to ..... @ "eDate>% @ AND eDate <% @", date1, date2] Jeszcze raz dziękuję. – user2228755

+0

dlaczego dodajesz 'NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit' w 'components: fromDate:' po prostu go odrzucić? – vikingosegundo

+0

Moja zła. To był kod wklejony z projektu, który faktycznie używa tych składników. Zaniedbałem ich usunąć na potrzeby tego postu. Zmienię to teraz;] Dzięki za wskazanie tego! – CaptainRedmuff

11

Podczas gdy w ludzkiej komunikacji data jest często równa z dniem, to nie jest tak samo z obiektami NSDate: NSDate reprezentuje jedną chwilę w czasie. Daty, które różnią się w kilka sekund, nie są równe. I faktycznie nie reprezentują one dni, miesiąca, roku w ogóle, ponieważ różni się to od systemu kalendarza do systemu kalendarzy

musisz sam zdefiniować, czy daty w tej samej minucie, godzinie, dniu ... są równe. Więc w zasadzie musisz nauczyć program, aby umożliwić trochę rozmytości.

tutaj rozdzielczości minut

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

dla dat w tym samym dniu (świadome stref czasowych i czasu letniego razy) po prostu by to zmienić:

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

Mam to, dziękuję ci również za odpowiedź. – user2228755

+1

Moim zdaniem jest to znacznie lepsze niż zaakceptowana odpowiedź, ponieważ obejmuje różne kalendarze i nie koduje godzin rozpoczęcia i zakończenia dnia. – SwampThingTom

0

ja niedawno spędził trochę czasu próbując rozwiązać ten sam problem i zostały rozwiązane następujące kwestie, zaktualizowane na iOS 8 i nowsze ...

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

... i NSPredicate za podstawowe dane NSFetchRequest (jak już przedstawiono powyżej w innych odpowiedzi) ...

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

mogę dostać pracy z pewnymi modyfikacjami zaakceptowanej odpowiedzi i korzystania z iOS 8 API dla tworzyć daty z przesunięciem czasu.Kod:

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

nadzieję, że pomoże ktoś

+1

To zadziałało dla mnie jak urok ... przegłosowany! – NSPratik

Powiązane problemy