I have start Date attribute in core data, and i want to fetch the items along with grouping according to startDate,
But startDate is basically having timeComponent in it, but i want grouping to be based on yyyy-mm-dd,
This is the code i am using
NSError *error = nil;
NSFetchRequest *request = [NSFetchRequest new];
NSManagedObjectContext *context = self.managedObjectContext;
request.entity = [CalendarItem entityInManagedObjectContext:context];
NSExpression *startExpr = [NSExpression expressionForKeyPath:@"start"];
NSExpression *countExpr = [NSExpression expressionForFunction:@"count:" arguments:[NSArray arrayWithObject:startExpr]];
NSExpressionDescription *exprDesc = [[NSExpressionDescription alloc] init];
[exprDesc setExpression:countExpr];
[exprDesc setExpressionResultType:NSInteger64AttributeType];
[exprDesc setName:@"count"];
[request setPropertiesToGroupBy:@[@"start"]];
[request setPropertiesToFetch:[NSArray arrayWithObjects:@"start", exprDesc, nil]];
[request setResultType:NSDictionaryResultType];
NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&error];
This is the Output i am getting:
Printing description of results:
<_PFArray 0x600001e3a700>(
{
count = 1;
start = "2021-09-14 03:30:00 +0000";
},
{
count = 1;
start = "2021-09-14 04:00:00 +0000";
},
{
count = 1;
start = "2021-09-16 09:30:00 +0000";
},
{
count = 1;
start = "2021-11-11 00:00:00 +0000";
},
{
count = 1;
start = "2021-11-11 04:00:00 +0000";
},
{
count = 1;
start = "2021-11-11 06:00:00 +0000";
},
{
count = 1;
start = "2021-11-12 00:00:00 +0000";
}
)
Expected Result:
{
count = 2
start = 2021-09-14
}
{
count = 1
start = 2021-09-16
}
{
count = 3
start = 2021-11-11
}
{
count = 1;
start = "2021-11-12
}
Core Data "date" properties, as you've found, are actually timestamps. They include the time of day, even though they're called "date". You can't tell Core Data to use only part of the value of a date attribute-- it's all or nothing.
To get the kind of grouping you want, you need to create another property where the value is only the value you need instead of a timestamp that includes extra details you don't need. Here, that would be a date where the hour, minute, and second are all set to zero, so that those details don't affect grouping.
One way to do this is to make a new date object with that change and save it in a new property. You could call it
trimmedDate. Then any time you set the date on an instance, also set trimmedDate, with code that's something likeThen use this new value for grouping.