Core Data Predicate Filter By Today's Date - swift

How can I filter Core Data Managed Objects by their Date attribute in Swift?
The goal is to filter fetched objects by today's date.

You can't simply use to compare your date to today's date:
let today = Date()
let datePredicate = NSPredicate(format: "%K == %#", #keyPath(ModelType.date), today)
It will show you nothing since it's unlikely that your date is the EXACT comparison date (it includes seconds & milliseconds too)
The solution is this:
// 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
It's by far the easiest & shortest way of showing only objects which have today's date.

In swift4, Lawrence413's can be simplify a bit:
//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)
It get rid of the component part, makes the code have better readability.

Might be helpful to add to Lawrence413's answer that to filter a list of records with an attribute holding today's date, you could use:
let fromPredicate = NSPredicate(format: "datetime >= %#", dateFrom as NSDate)
let toPredicate = NSPredicate(format: "datetime < %#", dateToUnwrapped as NSDate)
...Where "datetime is the name of the attribute"

Related

CoreData - How to filter for partial matches?

I am using CoreData for a project - My CoreData entity has an attribute "date", type Date. I am trying to filter the data based on mm/dd/yy only. Here is what I have so far
fetchRequest.predicate = NSPredicate(format: "date = %#", date as! NSDate)
This doesn't work because "date" includes the time, which makes each entry different even though the calendar date is the same.
I have tried parsing the date into a string mm/dd/yy and changing the format to "date CONTAINS stringDate", but that didn't work- I don't think I should be able to search for a string inside a Date.
I have looked through the documentation on predicates, but I cannot figure out how to apply to type Date.
The approach you need to take here is to create a predicate where you test if the date attribute is between the start of the day and at the end of the day so you will get a match for any time of that day.
let predicate = NSPredicate(format: "date >= %# && date <= %#",
argumentArray: [startDate, endDate]
where you calculate the dates from a given date inputDate as
let startDate = Calendar.current.startOfDay(for: inputDate)
let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate)!

Core Data NSPredicate - Match Dates

I have an entity in core data that stores a Date property date. I have an #State property in my View selectedDate that is of type Date.
I want to use a fetch request to retrieve all of the entities in the database with a date matching selectedDate. I want to do this exclusive of the time; for example selectedDate could be 15/03/2022 at 12:07pm, and date could be 15/03/2022 at 9:05am - I would like these to be matched.
I have tried to use the following (although this will not achieve the desired time behaviour):
request.predicate = NSPredicate(format: "date == %#", selectedDate.timeIntervalSince1970)
However, when running the app I get the following error, on the predicate line:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x41d88c207fdc4b4d)
Does anyone know how to do this?
First of all the exception occurs because the placeholder %# is wrong. %# is for objects, a Double value is represented by %f.
Second of all if you want to fetch all dates which are in a specific day you have to create a date range (0:00–23:59) of that day.
Using Calendar you get 0:00 with startOfDay(for:) and the end of the day by adding a day and the < operator.
For example
let calendar = Calendar.current
let startDate = calendar.startOfDay(for: selectedDate)
let endDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
let predicate = NSPredicate(format: "date >= %# AND date < %#", argumentArray: [startDate, endDate]))

How can I filter a Realm List by Date Swift NSPredicates

I want to filter my Realm List by Date. The Filter should show me every listed Item by month. I select the month "June" and the app should show me everything that was sold in June.
this is the code I tried but it obviously doesnt worked out.
let date = Date()
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd"
let formattedDate = format.string(from: date)
print(formattedDate)
let current = Calendar.current
let componentDate = current.component(.month, from: date)
print(current.component(.month, from: date))
let articles = realm.objects(Article.self).filter("artSoldDate = \(componentDate)")
return articles
You would need to use a date range filter. You would need to start the range at a specific date and end it at a certain date. For example,
let predicate = NSPredicate(format: "artSoldDate >= %# AND artSoldDate <= %#", startDate, endDate)
let result = realm.objects(Art.self).filter(predicate)
Your example seems to try and check when the artSoldDate is exactly some date.

Swift NSDate get current date but strip Year, Month, and Day

I am trying to get the current date using swift. I have that taken care of but it gets the year month and day and I really only want the current hour and minute. The reason being is that I am trying to later on compare a created date that only has an hour and minute. I am currently just using this
let currentDate = NSDate()
Thank you
let calendar = Calendar.autoupdatingCurrent
let components = calendar.dateComponents([.hour, .minute], from: Date())
let hour = components.hour
let minute = components.minute

Extract entity from last seven days core data

I am currently working with core data to store meals. My entities are date (Date), foods (string) and drinks (string). Now I want to extract all the foods stored for the last seven days. How would I do this? I know i should somehow use NSPredicate, but I can't figure out how exactly.
Get the current calendar
let calendar = NSCalendar.currentCalendar()
Get the current date
let now = NSDate()
Subtract 7 days from current date
let sevenDaysAgo = calendar.dateByAddingUnit(.Day, value: -7, toDate: now, options: [])!
Get the start of the day 7 days ago
let startDate = calendar.startOfDayForDate(sevenDaysAgo)
Create the predicate, literal date is the Core Data attribute
let predicate = NSPredicate(format:"(date >= %#) AND (date < %#)", startDate, now)