2016-02-28 57 views
1

我被困在我的核心數據模型的問題和涉及日期的提取請求。如何使用NSPredicate使用今天的NSDate獲取對象?

我在具有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年2月28日22時02分01秒+0000

我想獲取只有相同日期的對象,忽略小時,分鐘和秒。我需要做什麼?

我也試圖創建另一個的NSDate使用組件:

let components = cal.components([.Day , .Month, .Year ], fromDate: today) 
let newDate = cal.dateFromComponents(components) 

但結果是一樣的。我究竟做錯了什麼?

回答

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

由於此代碼不處理秒,納秒和它可能在邊緣情況下失敗的時代。此類方法更自然的地方是NSDate的擴展,而不是輔助類。 – vikingosegundo

+0

這兩個優點 - 如果你有改進,讓自由! – sschale

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]