এনএসপ্রেডিকেট: এনএসডিট সংস্থার দিন অনুযায়ী অবজেক্ট ফিল্টার করা


123

আমার একটি NSDateসম্পত্তি সহ একটি কোর ডেটা মডেল রয়েছে । আমি দিনের বেলা ডাটাবেস ফিল্টার করতে চাই। আমি ধরে নিই যে সমাধানটি একটির সাথে জড়িত থাকবে NSPredicateতবে আমি কীভাবে এটি সব একসাথে রাখব তা নিশ্চিত নই।

আমি কীভাবে দুটি NSDateব্যবহার করে দিনের তুলনা করতে জানি NSDateComponentsএবং NSCalendarকীভাবে আমি এটির সাথে ফিল্টার করব NSPredicate?

সম্ভবত আমার NSManagedObjectসাবক্লাসে এমন একটি বিভাগ তৈরি করা দরকার যা কেবল বছর, মাস এবং দিন দিয়ে সবেমাত্র তারিখ ফিরে আসতে পারে। তারপরে আমি এটিকে তুলনা করতে পারি NSPredicate। এটি কি আপনার প্রস্তাবনা, বা আরও সহজ কিছু আছে?

উত্তর:


193

প্রদত্ত 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];

4
আমাদের যদি কেবল একটি তারিখ থাকে?
ওয়াসিম

4
দেখে মনে হচ্ছে আপনি ব্যবহার করতে পারেন ==। যদিও আপনি যদি দিনের বেলা অনুসন্ধান করে থাকেন তবে মনে রাখবেন যে এনএসডিট একটি তারিখ এবং সময় - আপনি একটি মধ্যরাত থেকে মধ্যরাতের ব্যাপ্তিটি ব্যবহার করতে পারেন।
jlstrecker

1
কীভাবে সূচনা ও শেষ তারিখটি সেটআপ করবেন তার উদাহরণ, নীচে আমার উত্তরটি দেখুন
d.ennis

@jlstrecker আপনি কীভাবে মধ্যরাত থেকে মধ্যরাত্রি ব্যাপ্তি ব্যবহার করবেন তা উদাহরণ দেখিয়ে দিতে পারেন। উদাহরণস্বরূপ: আমার ২ টি একই দিন তবে সময় ভিন্ন। এবং আমি দিনের বেলা ফিল্টার করতে চাই (আমি সময় সম্পর্কে যত্নশীল না)। আমি এটা কিভাবে করবো?
iosMentalist

3
@ শ্যাডি উপরের উদাহরণে, আপনি startDate2012-09-17 0:00:00 এ এবং 2012-09-18 0:00:00 এ সেট করতে পারেন endDateএবং </ তারিখ <শেষ তারিখের তারিখের প্রিডিকেট pred এটি সর্বদা ২০১২-০9-১ catch এ ধরা পড়বে।
jlstrecker

63

উপরোক্ত প্রদত্ত উত্তরে কীভাবে স্টার্টডেট এবং শেষ তারিখ সেট আপ করবেন তার উদাহরণ:

...

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth ) fromDate:[NSDate date]];
//create a date with these components
NSDate *startDate = [calendar dateFromComponents:components];
[components setMonth:1];
[components setDay:0]; //reset the other components
[components setYear:0]; //reset the other components
NSDate *endDate = [calendar dateByAddingComponents:components toDate:startDate options:0];
predicate = [NSPredicate predicateWithFormat:@"((date >= %@) AND (date < %@)) || (date = nil)",startDate,endDate];

...

এখানে আমি এক মাসের মধ্যে সমস্ত এন্ট্রি সন্ধান করছিলাম। এটি উল্লেখ করার মতো, যে এই উদাহরণটি 'শূন্য' তারিখটি কীভাবে সন্ধান করতে হয় তাও দেখায়।


10

সুইফটে আমি এর মতো কিছু পেয়েছি:

        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)"এনএসপিডিকেটে তারিখের তুলনা করার জন্য স্ট্রিং ইন্টারপোলেশন কাজ করে না তা আবিষ্কার করার জন্য আমার একটি কঠিন সময় ছিল ।


এই উত্তরের জন্য আপনাকে ধন্যবাদ। সুইফট 3 সংস্করণ নীচে যুক্ত করা হয়েছে।
ডিএস

9

তারিখের জন্য সুইফট 3.0 এক্সটেনশন:

extension Date{

func makeDayPredicate() -> NSPredicate {
    let calendar = Calendar.current
    var components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)
    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: "day >= %@ AND day =< %@", argumentArray: [startDate!, endDate!])
}
}

তারপরে ব্যবহার করুন:

 let fetchReq = NSFetchRequest(entityName: "MyObject")
 fetchReq.predicate = myDate.makeDayPredicate()

8

আমি গ্লাচো নেভস থেকে সুইফট ২.০-তে উত্তরটি পোর্ট করেছি এবং এটিকে একটি ফাংশনের অভ্যন্তরে আবৃত করি যা একটি তারিখ পায় এবং NSPredicateসংশ্লিষ্ট দিনের জন্য ফেরত দেয় :

func predicateForDayFromDate(date: NSDate) -> NSPredicate {
    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
    let components = calendar!.components([.Year, .Month, .Day, .Hour, .Minute, .Second], 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)

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

এই উত্তরের জন্য আপনাকে ধন্যবাদ। সুইফট 3 সংস্করণ নীচে যুক্ত করা হয়েছে।
ডিএস

6

রাফেলের উত্তরে যুক্ত করা (অবিশ্বাস্যভাবে কার্যকর, আপনাকে ধন্যবাদ!), সুইফট 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!])
}

1

আমি সম্প্রতি এই একই সমস্যাটি সমাধান করার চেষ্টা করে কিছুটা সময় ব্যয় করেছি এবং শুরু এবং শেষের তারিখগুলি প্রস্তুত করার জন্য বিকল্পগুলির তালিকায় নিম্নলিখিতটি যুক্ত করেছি (আইওএস 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]]

0

আমার জন্য এটি কাজ করা হয়।

NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit ) fromDate:[NSDate date]];
    //create a date with these components
    NSDate *startDate = [calendar dateFromComponents:components];
    [components setMonth:0];
    [components setDay:0]; //reset the other components
    [components setYear:0]; //reset the other components
    NSDate *endDate = [calendar dateByAddingComponents:components toDate:startDate options:0];

    startDate = [NSDate date];
    endDate = [startDate dateByAddingTimeInterval:-(7 * 24 * 60 * 60)];//change here

    NSString *startTimeStamp = [[NSNumber numberWithInt:floor([endDate timeIntervalSince1970])] stringValue];
    NSString *endTimeStamp = [[NSNumber numberWithInt:floor([startDate timeIntervalSince1970])] stringValue];


   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"((paidDate1 >= %@) AND (paidDate1 < %@))",startTimeStamp,endTimeStamp];
    NSLog(@"predicate is %@",predicate);
    totalArr = [completeArray filteredArrayUsingPredicate:predicate];
    [self filterAndPopulateDataBasedonIndex];
    [self.tableviewObj reloadData];
    NSLog(@"result is %@",totalArr);

আমি বর্তমান তারিখ থেকে 7 দিন পিছনে অ্যারে ফিল্টার করেছি। মানে আমি বর্তমান তারিখ থেকে এক সপ্তাহের ডেটা পাচ্ছি। এই কাজ করা উচিত.

দ্রষ্টব্য: আমি তারিখটি রূপান্তর করছি যা মিলি সেকেন্ডের সাথে 1000 দ্বারা আসছে এবং তার পরে তুলনা করা হচ্ছে। আপনার কোনও স্পষ্টতা প্রয়োজন হলে আমাকে জানান।


আপনার উত্তরে completeArrayএটির অ্যারে রয়েছে dictionaryবা dataModel আমি ডেটামডেলে আবেদন করতে চাই।
ौर্যা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.