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)
}
}