web-dev-qa-db-ja.com

今日の日付によるコアデータ述語フィルター

これに問題があり、SO)で適切な答えが見つからなかったので、ここに小さなチュートリアルを残します。

目標は、フェッチされたオブジェクトを今日の日付でフィルタリングすることです。

注:Swift 3互換です。

9
Lawrence413

単に自分の日付を今日の日付と比較するために使用することはできません。

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: "%@ >= %@", date as NSDate, dateFrom as NSDate)
let toPredicate = NSPredicate(format: "%@ < %@", date as NSDate, dateTo as NSDate)
let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])
fetchRequest.predicate = datePredicate

これは、今日の日付を持つオブジェクトのみを表示する最も簡単で最短の方法です。

23
Lawrence413

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)

component部分が削除され、コードの可読性が向上します。

4
mmk