如何使用 NSPredicate 获取今天的 NSDate 对象?
Posted
技术标签:
【中文标题】如何使用 NSPredicate 获取今天的 NSDate 对象?【英文标题】:How fetch objects with NSDate of today using NSPredicate? 【发布时间】:2016-02-28 22:12:54 【问题描述】:我的核心数据模型和涉及日期的获取请求遇到问题。
我在具有 NSDate 属性的实体中有一些对象; 我需要提取今天日期的对象,但我总是从这段代码中得到 nil:
public func getObjectsOfToday() -> Array<myObject>?
let entityDescription = NSEntityDescription.entityForName("Objects", inManagedObjectContext: DataAccess.sharedInstance.managedObjectContext)
let request = NSFetchRequest()
request.entity = entityDescription
request.returnsObjectsAsFaults = false
let today = NSDate()
request.predicate = NSPredicate(format: "(dateStart => %@) AND (dateStart <= %@)", today, today)
var objects: [AnyObject]?
do
objects = try DataAccess.sharedInstance.managedObjectContext.executeFetchRequest(request)
catch let error as NSError
print(error)
objects = nil
return objects as? Array<Objects>
我认为是 NSPredicate 的问题,因为它还考虑了小时、分钟和秒。如果我今天打印是这样的:
今日打印说明:2016-02-28 22:02:01 +0000
但是我想获取具有相同日期的对象,忽略小时、分钟和秒。我需要做什么?
我还尝试使用组件创建另一个 NSDate:
let components = cal.components([.Day , .Month, .Year ], fromDate: today)
let newDate = cal.dateFromComponents(components)
但结果是一样的。我做错了什么?
【问题讨论】:
【参考方案1】:我所做的是将它与一天的开始和结束进行比较,并使用几个辅助函数来计算它们:
class DateHelper
internal class func startOfDay(day: NSDate) -> NSDate
let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
let unitFlags: NSCalendarUnit = [.Minute, .Hour, .Day, .Month, .Year]
let todayComponents = gregorian!.components(unitFlags, fromDate: day)
todayComponents.hour = 0
todayComponents.minute = 0
return (gregorian?.dateFromComponents(todayComponents))!
internal class func endOfDay(day: NSDate) -> NSDate
let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
let unitFlags: NSCalendarUnit = [.Minute, .Hour, .Day, .Month, .Year]
let todayComponents = gregorian!.components(unitFlags, fromDate: day)
todayComponents.hour = 23
todayComponents.minute = 59
return (gregorian?.dateFromComponents(todayComponents))!
所以在你的代码中,你会调用:
request.predicate = NSPredicate(format: "(dateStart => %@) AND (dateStart <= %@)", DateHelper.startOfDay(today), DateHelper.endOfDay(today))
【讨论】:
由于此代码不处理秒、纳秒和时代,因此在边缘情况下它可能会失败。此类方法更自然的地方是 NSDate 上的扩展而不是辅助类。 这两点都很好——如果你有改进的地方,请随意!【参考方案2】:创建一个开始日期,获取一天的长度(间隔),将间隔添加到开始日期以获得第二天的开始。
var startOfToday: NSDate?
var interval: NSTimeInterval = 0
NSCalendar.currentCalendar().rangeOfUnit(.Day, startDate: &startOfToday, interval: &interval, forDate: NSDate())
let startOfTomorrow = startOfToday!.dateByAddingTimeInterval(interval)
创建谓词
let predicate = NSPredicate(format: "dateStart >= %@ AND dateStart < %@", startOfToday, startOfTomorrow)
我使用以下测试代码没有核心数据的麻烦
import Foundation
let dates:[NSDate] =
var dates:[NSDate] = []
dates.append(
let c = NSDateComponents()
c.year = 2016
c.month = 2
c.day = 1
return NSCalendar.currentCalendar().dateFromComponents(c)!
())
dates.append(
let c = NSDateComponents()
c.year = 2016
c.month = 2
c.day = 3
return NSCalendar.currentCalendar().dateFromComponents(c)!
())
dates.append(
let c = NSDateComponents()
c.year = 2016
c.month = 3
c.day = 1
return NSCalendar.currentCalendar().dateFromComponents(c)!
())
dates.append(
let c = NSDateComponents()
c.year = 2016
c.month = 2
c.day = 28
c.hour = 12
c.minute = 30
return NSCalendar.currentCalendar().dateFromComponents(c)!
())
dates.append(
let c = NSDateComponents()
c.year = 2016
c.month = 2
c.day = 28
c.hour = 11
c.minute = 15
return NSCalendar.currentCalendar().dateFromComponents(c)!
())
return dates
()
var startOfToday: NSDate?
var interval: NSTimeInterval = 0
NSCalendar.currentCalendar().rangeOfUnit(.Day, startDate: &startOfToday, interval: &interval, forDate: NSDate())
if let startOfToday = startOfToday
let startOfTomorrow = startOfToday.dateByAddingTimeInterval(interval)
let predicate = NSPredicate(format: "self >= %@ AND self < %@", startOfToday, startOfTomorrow)
let filteredArray = dates.filter(predicate.evaluateWithObject($0))
print(filteredArray)
结果:
[2016-02-28 11:30:00 +0000, 2016-02-28 10:15:00 +0000]
【讨论】:
以上是关于如何使用 NSPredicate 获取今天的 NSDate 对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 NSPredicate 和 CloudKit 获取特定用户的最新帖子?