Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone NSPredicate-用于查找在特定日期范围内发生的事件_Iphone_Core Data_Nsdate_Nspredicate - Fatal编程技术网

Iphone NSPredicate-用于查找在特定日期范围内发生的事件

Iphone NSPredicate-用于查找在特定日期范围内发生的事件,iphone,core-data,nsdate,nspredicate,Iphone,Core Data,Nsdate,Nspredicate,这比刚才要复杂一点 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startDate >= %@ AND endDate <= %@", startDay,endDay]; NSPredicate*predicate=[NSPredicate predicateWithFormat:@“startDate>=%@和endDate您需要的是: NSPredicate *predicate = [NSPredic

这比刚才要复杂一点

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startDate >= %@ AND endDate <= %@", startDay,endDay];
NSPredicate*predicate=[NSPredicate predicateWithFormat:@“startDate>=%@和endDate您需要的是:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startDate <= %@ AND endDate >= %@", endDay, startDay];
NSPredicate*谓词=[NSPredicate谓词格式:@“startDate=%@”,endDay,startDay];

换句话说,您正在消除在范围结束后开始或在开始前结束的事件,即与范围有空交叉点的事件。

以下是一种构建谓词的方法,用于检索在给定日期发生的非周期性事件(周期性事件需要额外处理):

-(NSPredicate*)谓词RetrieveEventsfordate:(NSDate*)aDate{
//首先检索给定日期的日、工作日、月和年组件
NSCalendar*gregorian=[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents*todayComponents=[公历成分:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit)fromDate:aDate];
NSInteger theDay=[今天];
NSInteger theMonth=[Today Components month];
NSInteger theYear=[Today Components year];
//现在,使用这些组件为输入日期构建NSDate对象
NSDateComponents*components=[[NSDateComponents alloc]init];
[组件设置日期:theDay];
[组件设置月份:每月];
[组件设置年份:年份];
NSDate*thisDate=[gregorian dateFromComponents:components];
[组件发布];
//为aDate第二天构建NSDate对象
NSDateComponents*offsetComponents=[[NSDateComponents alloc]init];
[抵销组件设定日:1];
NSDate*nextDate=[gregorian Date ByAddingComponents:offsetComponents toDate:thisDate选项:0];
[抵消组件发布];
[公历释放];
//构建谓词
NSPredicate*谓词=[NSPredicate谓词格式:@“开始日期<%@&&endDate>%@”,下一个日期,这个日期];
返回谓词;
}

谓词几乎等于@Tony提出的谓词,只是它不检查是否相等。原因如下。假设您有一个从12月8日23:00开始到12月9日00:00结束的事件。如果您检查的事件的结束日期是给定日期的>=而不是>,则您的应用程序将在12月8日和9日报告该事件,即c显然是错误的。尝试将此类活动添加到iCal和Google日历中,您将看到该活动仅出现在12月8日。在实践中,您不应假设某一天在23:59:59结束(尽管这当然是正确的):您需要将午夜视为某一天的最后一秒(关于活动的结束)。另外,请注意,这并不能阻止午夜开始的事件。

Massimo Camaro给出了一个很好的答案。我冒昧地将其移植到Swift,并对其进行了一些修改,以支持不同的列名

Swift 2.0
func-predicateTorerieveEventsfordate(aDate:NSDate,predicateColumn:String)->NSPredicate{
//首先检索给定日期的日、工作日、月和年组件
设gregorian=NSCalendar(日历标识符:NSCalendarIdentifierGregorian)
让todayComponents=gregorian?.components([.Day、.Month、.Year],fromDate:aDate)
让这一天=今天组件?天
让theMonth=今天组件?月份
让年份=今天组件?年
//现在,使用这些组件为输入日期构建NSDate对象
let components=NSDateComponents()
组件。天=天!
components.month=每月!
components.year=年份!
设thisDate=gregorian?.dateFromComponents(components)
//为aDate第二天构建NSDate对象
let offsetComponents=NSDateComponents()
offsetComponents.day=1
设nextDate=gregorian?.dateByAddingComponents(offsetComponents,toDate:thisDate!,选项:NSCalendarOptions(rawValue:0))
//构建谓词
让predicate=NSPredicate(格式:“\(predicateColumn)>=%@&\(predicateColumn)<%@,thisDate!,nextDate!)
返回谓词
}

虽然建议的解决方案是正确的,但也相当冗长。我已在Swift 3.0中重新实现了它:

import Foundation

extension NSPredicate {

    static func filter(key: String, onDayRangeForDate date: Date, calendar: Calendar = Calendar(identifier: .gregorian)) -> NSPredicate {

        let dateComponents = calendar.dateComponents([.day, .month, .year], from: date)

        let startOfDay = calendar.date(from: dateComponents)!

        let offsetComponents = NSDateComponents()
        offsetComponents.day = 1
        let endOfDay = calendar.date(byAdding: offsetComponents as DateComponents, to: startOfDay)!

        return NSPredicate(format: "\(key) >= %@ && \(key) < %@",
            startOfDay as NSDate, endOfDay as NSDate)
    }
}
<代码>导入基础 扩展预测{ 静态func筛选器(键:字符串,onDayRangeForDate日期:日期,日历:日历=日历(标识符:。格里高利))->NSPredicate{ 让dateComponents=calendar.dateComponents([.day、.month、.year],from:date) 让startOfDay=calendar.date(from:dateComponents)! let offsetComponents=NSDateComponents() offsetComponents.day=1 让endOfDay=calendar.date(通过将:offsetComponents添加为DateComponents,添加到:startOfDay)! 返回NSPredicate(格式:“\(键)>=%@&\(键)<%@”, 开始日期为NSDate,结束日期为NSDate) } }
@massimo您也可以更新重复事件的答案吗?@JamalZafar,我对重复事件的谓词要复杂得多,很长,而且不是自包含的,因为它依赖于第三方库。此外,使用此添加更新答案真的没有意义,因为问题非常具体。
func predicateToRetrieveEventsForDate(aDate:NSDate, predicateColumn:String) -> NSPredicate {
    
    // start by retrieving day, weekday, month and year components for the given day
    let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
    let todayComponents = gregorian?.components([.Day, .Month, .Year], fromDate: aDate)
    let theDay = todayComponents?.day
    let theMonth = todayComponents?.month
    let theYear = todayComponents?.year
    
    // now build a NSDate object for the input date using these components
    let components = NSDateComponents()
    components.day = theDay!
    components.month = theMonth!
    components.year = theYear!
    let thisDate = gregorian?.dateFromComponents(components)
    
    // build a NSDate object for aDate next day
    let offsetComponents = NSDateComponents()
    offsetComponents.day = 1
    let nextDate = gregorian?.dateByAddingComponents(offsetComponents, toDate: thisDate!, options: NSCalendarOptions(rawValue: 0))
    
    // build the predicate
    let predicate = NSPredicate(format: "\(predicateColumn) >= %@ && \(predicateColumn) < %@", thisDate!, nextDate!)
    
    return predicate
}
import Foundation

extension NSPredicate {

    static func filter(key: String, onDayRangeForDate date: Date, calendar: Calendar = Calendar(identifier: .gregorian)) -> NSPredicate {

        let dateComponents = calendar.dateComponents([.day, .month, .year], from: date)

        let startOfDay = calendar.date(from: dateComponents)!

        let offsetComponents = NSDateComponents()
        offsetComponents.day = 1
        let endOfDay = calendar.date(byAdding: offsetComponents as DateComponents, to: startOfDay)!

        return NSPredicate(format: "\(key) >= %@ && \(key) < %@",
            startOfDay as NSDate, endOfDay as NSDate)
    }
}