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)
Related
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)!
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]))
I have two date pickers. Let's say fromDatePicker and untilDatePicker. I set the untilDatePicker to current date (ex: 12/06/17) and I want to set the fromDatePicker into first date of the current month (ex: 01/06/17) but I don't have any idea to set the untilDatePicker.
I have read this question but it's not helped me much.
This is swift3 solution and how you set first day of current month in datePicker , if you need to get first of other month just change date variable with some day from that month
let date = NSDate()
let calendar = NSCalendar.current
let components = calendar.dateComponents([.year,.month], from: date as Date)
let startOfMonth = calendar.date(from: components)
self.datePicker.setDate(startOfMonth!, animated: true)
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"
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