I have an app that has several time entries with a date saved as NSDate.
I would like to use a fetch request to filter for a certain year and month that I get from somewhere else. How can I use NSPredicate to filter for a year and month?
let predicate = NSPredicate(format: "%K == %D && %K == %D", ???, selectedMonth, ???, selectedYear)
Update
Using the help Raki pointed out I came up with the following code:
var dateComp = DateComponents()
dateComp.year = Int(selectedYear)
dateComp.month = Int(selectedMonth)
dateComp.day = 1
let calendar = Calendar.current
let firstDayOfTheMonth = calendar.date(from: dateComp)
var oneMonth = DateComponents()
oneMonth.month = 1
let beginningOfNextMonth = calendar.date(byAdding: oneMonth, to: firstDayOfTheMonth!)
And the predicate:
let predicate = NSPredicate(format: "date >= %@ AND date < %@", firstDayOfTheMonth as! CVarArg, beginningOfNextMonth as! CVarArg)
I get a SIGABRT with the following message:
Could not cast value of type 'Foundation.Date' (0x1073a0ae0) to 'Swift.CVarArg' (0x1196851c8).
Xcode suggested I add "as! CVarArg"
Update 2
The following predicate worked now:
let predicate = NSPredicate(format: "%K >= %@ && %K < %@", "date", firstDayOfTheMonth! as NSDate, "date", beginningOfNextMonth! as NSDate)
You cannot predicate like this, but you can create two Dates
from your month and year which start day of month and end day of month.
Now you need to simply predicate like this way.
let predicate = NSPredicate(format: "%K >= %@ && %K <= %@", "DateAttribute", startDateOfMonth as NSDate, "DateAttribute", endDateOfMonth as NSDate)
Edit: If you don't know how to create date for startDateOfMonth
and endDateOfMonth
, then you can create it using DateComponents
.
let selectedMonth = 11
let selectedYear = 2015
var components = DateComponents()
components.month = selectedMonth
components.year = selectedYear
let startDateOfMonth = Calendar.current.date(from: components)
//Now create endDateOfMonth using startDateOfMonth
components.year = 0
components.month = 1
components.day = -1
let endDateOfMonth = Calendar.current.date(byAdding: components, to: startDate!)