【问题标题】:Core Data Predicate Filter By Today's Date按今天日期过滤的核心数据谓词
【发布时间】:2017-03-11 18:15:43
【问题描述】:

如何在 Swift 中通过 Date 属性过滤核心数据托管对象?

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

【问题讨论】:

标签: swift core-data swift3 nspredicate


【解决方案1】:

您不能简单地用来比较您的日期和今天的日期:

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

这是迄今为止仅显示具有今天日期的对象的最简单和最短的方法。

【讨论】:

  • 不要使用 86400 秒作为一天的持续时间(想想夏令时转换)。使用正确的日历方法。将两个日期作为数组传递是错误的,尝试并打印谓词!
  • 您的第一个示例 NSPredicate(format: "date == Date()") 实际上会崩溃
  • 是的,86400 秒是一个基本的实现。我会用更好的解决方案更新答案。并感谢阵列提醒。您可以传递一个参数数组。使用更新后的功能,代码可以正常工作。
  • fetchRequest 在哪里?
  • 这行let fromPredicate = NSPredicate(format: "%@ &gt;= %K", dateFrom as NSDate, #keyPath(ModelType.date))应该替换成let fromPredicate = NSPredicate(format: "%@ &lt;= %K", dateFrom as NSDate, #keyPath(ModelType.date))(注意小于等于而不是大于等于)
【解决方案2】:

在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部分,使代码具有更好的可读性。

【讨论】:

  • 我认为 @lawrence413 正在为 swift3 寻找解决方案。
【解决方案3】:

可能有助于添加到 Lawrence413 的回答中,即过滤具有今天日期属性的记录列表,您可以使用:

let fromPredicate = NSPredicate(format: "datetime >= %@", dateFrom as NSDate)
let toPredicate   = NSPredicate(format: "datetime < %@",  dateToUnwrapped as NSDate)

...其中“日期时间是属性的名称”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 2017-09-12
    相关资源
    最近更新 更多