问题
H. I have an entity called Agendadate and one called AgendaEvent. AgendaEvent has a many to many relation with AgendaDate (agendaDates).
in my AgendaDate i have an object dates (of type Date).
I'm using a predicate like so:
fetchRequest.predicate = NSPredicate(format: "ANY agendaDates.dates == %@", date as CVarArg)
I'm trying to format dates to have this:
"dd MM yyyy" instead of "yyyy MM dd hh:mm:ss"
I need to compare in the predicate two dates but without the time? is it possible?
UPDATE----- Here's my function updated as you have suggested:
func agendaEventsWithDate(date: Date) -> NSFetchRequest<AgendaEvent>
{
// create a fetch request that will retrieve all the AgendaEvents.
let fetchRequest = NSFetchRequest<AgendaEvent>(entityName: "AgendaEvent")
// set the predicate to only keep AgendaEvents where the related AgendaDate's date matches the passed in date.
let cal = Calendar.current
let startOfDay = cal.startOfDay(for: eventDate)
let endOfDay = cal.date(byAdding: .day, value: 1, to: startOfDay)!
print(startOfDay)
print(endOfDay)
// fetchRequest.predicate = NSPredicate(format: "ANY agendaDates.agendaDates == %@", date as CVarArg)
fetchRequest.predicate = NSPredicate(format: "SUBQUERY(agendaDates, $a, $a.dates >= %@ AND $a.dates < %@).@count > 0",
startOfDay as NSDate, endOfDay as NSDate)
return fetchRequest
}
and here's the function that should configure the cell and take just the events which have the same date of the selected date:
func configuringCell(cell: CalendarAgendaCell, indexPath: IndexPath) {
for dates in calendar.selectedDates {
for dateOfEvent in myEventDate {
formatter.dateFormat = "dd MM yyyy"
let dateToCompare = formatter.string(from: dates)
formatter.dateFormat = "dd-MM-yyyy"
let comparingDate = formatter.date(from: dateToCompare)!
if dateOfEvent == dateToCompare {
myTempEvents = try! context.fetch(agendaEventsWithDate(date: comparingDate))
let myEvent = myTempEvents[indexPath.row]
cell.configureCell(agendaEvent: myEvent)
} else {
// the array is empty
}
}
}
}
回答1:
Don't use a custom string format for that purpose. You want to fetch all entries which are related to an Agendadate object with a date on the same day as the given day.
So you compute the start and end of that day first:
let date = Date()
let cal = Calendar.current
let startOfDay = cal.startOfDay(for: date)
let endOfDay = cal.date(byAdding: .day, value: 1, to: startOfDay)!
Then use this SUBQUERY:
let predicate = NSPredicate(format: "SUBQUERY(agendaDates, $a, $a.dates >= %@ AND $a.dates < %@).@count > 0",
startOfDay as NSDate, endOfDay as NSDate)
It tests $a.dates >= startDate AND $a.dates < endDate
for all
related objects, and yields true if there is at least one matching
the condition.
来源:https://stackoverflow.com/questions/46217293/swift-coredata-format-date-and-use-it-in-predicate