今天使用NSPredicate如何使用NSDate获取对象?

时间:2016-02-28 22:12:55

标签: ios swift core-data nsdate nspredicate

我遇到了我的核心数据模型和涉及日期的获取请求的问题。

我在具有NSDate属性的实体中有一些对象; 我需要提取具有今天日期的对象,但我总是从这段代码中删除:

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)

但结果却是一样的。我做错了什么?

2 个答案:

答案 0 :(得分:4)

我所做的是将它与当天的开始和结束进行比较,并有几个辅助函数来计算它们:

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

答案 1 :(得分:1)

创建开始日期,获取当天的长度(间隔),添加开始日期的间隔以获得第二天的开始。

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]