按今天日期筛选的核心数据谓词过滤器。

17

我该如何用Swift过滤Core Data托管对象的Date属性?

目标是按照今天的日期过滤获取的对象。


Pre-Swift 3的问题和答案在这里:http://stackoverflow.com/questions/35688952/how-fetch-objects-with-nsdate-of-today-using-nspredicate。 - Martin R
3个回答

48
你不能简单地使用来将你的日期与今天的日期进行比较:
let today = Date()
let datePredicate = NSPredicate(format: "%K == %@", #keyPath(ModelType.date), today)

由于日期包括秒和毫秒,所以它不太可能与精确比较日期完全相同,因此您将看不到任何内容。

解决方案如下:

// Get the current calendar with local time zone
var calendar = Calendar.current
calendar.timeZone = NSTimeZone.local

// Get today's beginning & end
let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
// Note: Times are printed in UTC. Depending on where you live it won't print 00:00:00 but it will work with UTC times which can be converted to local time

// Set predicate as date being today's date
let fromPredicate = NSPredicate(format: "%@ >= %K", dateFrom as NSDate, #keyPath(ModelType.date))
let toPredicate = NSPredicate(format: "%K < %@", #keyPath(ModelType.date), dateTo as NSDate)
let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])
fetchRequest.predicate = datePredicate

这是最简单、最快捷的方法,只显示今天日期的对象。


8
不要将86400秒用作一天的持续时间(考虑夏令时转换)。请使用适当的日历方法。将两个日期都传递为数组是错误的,请尝试并打印谓词! - Martin R
1
你的第一个例子 NSPredicate(format: "date == Date()") 实际上会崩溃 - Martin R
fetchRequest在哪里? - mAc
我该如何将这段代码嵌入到 @FetchRequest 中呢?@FetchRequest( entity: CDReminder.entity(), sortDescriptors:[], predicate: NSPredicate(format: "date == %@", Date() as CVarArg) )var reminder: FetchedResults<CDReminder> - Mert Köksal
8
这行代码 let fromPredicate = NSPredicate(format: "%@ >= %K", dateFrom as NSDate, #keyPath(ModelType.date)) 应该替换为 let fromPredicate = NSPredicate(format: "%@ <= %K", dateFrom as NSDate, #keyPath(ModelType.date)) (请注意,将大于或等于改为小于或等于)。 - otusweb
显示剩余3条评论

10
在Swift4中,Lawrence413的代码可以稍微简化一下:
//Get today's beginning & end
let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)

它去掉了“组件”部分,使代码更易读。

我认为@lawrence413正在寻找Swift3的解决方案。 - picsoung

6
可能对Lawrence413的回答有所帮助,如果要过滤带有今天日期属性的记录列表,可以使用以下代码:
let fromPredicate = NSPredicate(format: "datetime >= %@", dateFrom as NSDate)
let toPredicate   = NSPredicate(format: "datetime < %@",  dateToUnwrapped as NSDate)

... "datetime" 是该属性的名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接