代码之家  ›  专栏  ›  技术社区  ›  Jonathan Sterling

nspredicate:按nsdate属性的日期筛选对象

  •  118
  • Jonathan Sterling  · 技术社区  · 15 年前

    我有一个核心数据模型 NSDate 财产。我想按天筛选数据库。我认为解决方案将涉及 NSPredicate ,但我不知道该怎么把它们放在一起。

    我知道如何比较两天 新西兰 S使用 NSDateComponents NSCalendar ,但如何使用 NSPRD ?

    也许我需要在我的 NSManagedObject 子类,可以返回只有年、月和日的空日期。然后我可以用一个 NSPRD . 这是你的建议,还是有更简单的建议?

    8 回复  |  直到 6 年前
        1
  •  186
  •   diciu    15 年前

    给出一个nsdate* 开始日期 实际结束 以及nsmanagedobjectcontext* 莫克 :

    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];
    
        2
  •  62
  •   Mochi    6 年前

    关于如何设置上述给定答案的startdate和enddate的示例:

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

    我在这里搜索了一个月内的所有条目。值得一提的是,这个例子还展示了如何搜索“nil”日期实体。

        3
  •  10
  •   Glauco Neves    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)" 无法比较nspredicate中的日期。

        4
  •  8
  •   Community CDub    8 年前

    我把答案从 Glauco Neves swift 2.0并将其包装在一个函数中,该函数接收日期并返回 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!])
    }
    
        5
  •  8
  •   RawKnee    8 年前

    SWIFT 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()
    
        6
  •  6
  •   DS.    8 年前

    补充拉斐尔的回答(非常有用,谢谢!),为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!])
    }
    
        7
  •  1
  •   andrewbuilder    9 年前

    我最近花了一些时间试图解决同样的问题,并将以下内容添加到准备开始和结束日期的备选方案列表中(包括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]]
    
        8
  •  0
  •   Narasimha Nallamsetty Amit89    9 年前

    对我来说这是可行的。

    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,并在之后进行比较。如果你需要澄清,请告诉我。

    推荐文章