objective-c - NSPredicate: تصفية الكائنات حسب يوم خاصية NSDate




4 Answers

إعطاء NSDate * startDate و endDate و NSManagedObjectContext * moc :

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:@"EntityName" inManagedObjectContext:moc]];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];

لدي نموذج البيانات الأساسية مع خاصية NSDate . أريد تصفية قاعدة البيانات حسب اليوم. أفترض أن الحل سيشمل NSPredicate ، لكنني لست متأكدًا من كيفية وضع كل ذلك معًا.

أعرف كيفية مقارنة يوم اثنين من NSDateComponents باستخدام NSDateComponents و NSCalendar ، ولكن كيف يمكنني NSPredicate مع NSPredicate ؟

ربما أحتاج إلى إنشاء فئة في الفئة الفرعية NSManagedObject والتي يمكنها إرجاع التاريخ العاري مع العام والشهر واليوم فقط. ثم يمكنني مقارنة ذلك في NSPredicate . هل هذه توصيتك أم أن هناك شيئًا أكثر بساطة؟




في Swift حصلت على شيء مشابه لـ:

        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        let date = dateFormatter.dateFromString(predicate)
        let calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)
        let components = calendar!.components(
            NSCalendarUnit.CalendarUnitYear |
                NSCalendarUnit.CalendarUnitMonth |
                NSCalendarUnit.CalendarUnitDay |
                NSCalendarUnit.CalendarUnitHour |
                NSCalendarUnit.CalendarUnitMinute |
                NSCalendarUnit.CalendarUnitSecond, fromDate: date!)
        components.hour = 00
        components.minute = 00
        components.second = 00
        let startDate = calendar!.dateFromComponents(components)
        components.hour = 23
        components.minute = 59
        components.second = 59
        let endDate = calendar!.dateFromComponents(components)
        predicate = NSPredicate(format: "day >= %@ AND day =< %@", argumentArray: [startDate!, endDate!])

لقد واجهت صعوبة في اكتشاف أن الاستيفاء الداخلي "\(this notation)" لا يعمل لمقارنة التواريخ في NSPredicate.




إضافة إلى الإجابة رافائيل (مفيد بشكل لا يصدق ، شكرا لك!) ، لنقلها إلى Swift 3.

func predicateForDayFromDate(date: Date) -> NSPredicate {
    let calendar = Calendar(identifier: Calendar.Identifier.gregorian)
    var components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
    components.hour = 00
    components.minute = 00
    components.second = 00
    let startDate = calendar.date(from: components)
    components.hour = 23
    components.minute = 59
    components.second = 59
    let endDate = calendar.date(from: components)

    return NSPredicate(format: "YOUR_DATE_FIELD >= %@ AND YOUR_DATE_FIELD =< %@", argumentArray: [startDate!, endDate!])
}



لقد قضيت بعض الوقت في الآونة الأخيرة في محاولة حل هذه المشكلة نفسها وإضافة ما يلي إلى قائمة البدائل لإعداد تواريخ البدء والانتهاء (بما في ذلك الطريقة المحدّثة لنظام التشغيل iOS 8 والإصدارات الأحدث) ...

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

dateDay = <<USER_INPUT>>;

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



Related