Core Data如何按去除时间的NSDate(yyyy-mm-dd)分组查询
Core Data 按纯日期分组统计解决方案
你当前的问题根源是直接对带时间分量的start字段分组,导致同一天不同时间的数据被拆分为独立分组。你可以通过Core Data内置的日期提取函数,先分别取出start字段的年、月、日三个维度,再按这三个维度分组实现需求。
完整修改后代码
NSError *error = nil; NSFetchRequest *request = [NSFetchRequest new]; NSManagedObjectContext *context = self.managedObjectContext; request.entity = [CalendarItem entityInManagedObjectContext:context]; // 1. 定义提取年、月、日的表达式 NSExpression *yearExpr = [NSExpression expressionForFunction:@"extract:from:" arguments:@[@"year", [NSExpression expressionForKeyPath:@"start"]]]; NSExpressionDescription *yearDesc = [[NSExpressionDescription alloc] init]; yearDesc.name = @"year"; yearDesc.expression = yearExpr; yearDesc.expressionResultType = NSInteger32AttributeType; NSExpression *monthExpr = [NSExpression expressionForFunction:@"extract:from:" arguments:@[@"month", [NSExpression expressionForKeyPath:@"start"]]]; NSExpressionDescription *monthDesc = [[NSExpressionDescription alloc] init]; monthDesc.name = @"month"; monthDesc.expression = monthExpr; monthDesc.expressionResultType = NSInteger32AttributeType; NSExpression *dayExpr = [NSExpression expressionForFunction:@"extract:from:" arguments:@[@"day", [NSExpression expressionForKeyPath:@"start"]]]; NSExpressionDescription *dayDesc = [[NSExpressionDescription alloc] init]; dayDesc.name = @"day"; dayDesc.expression = dayExpr; dayDesc.expressionResultType = NSInteger32AttributeType; // 2. 定义统计数量的表达式 NSExpression *countExpr = [NSExpression expressionForFunction:@"count:" arguments:@[[NSExpression expressionForKeyPath:@"objectID"]]]; NSExpressionDescription *countDesc = [[NSExpressionDescription alloc] init]; [countDesc setExpression:countExpr]; [countDesc setExpressionResultType:NSInteger64AttributeType]; [countDesc setName:@"count"]; // 3. 配置查询参数 [request setPropertiesToGroupBy:@[yearDesc, monthDesc, dayDesc]]; [request setPropertiesToFetch:@[yearDesc, monthDesc, dayDesc, countDesc]]; [request setResultType:NSDictionaryResultType]; // 4. 执行查询 NSArray *results = [context executeFetchRequest:request error:&error]; // 5. 结果格式化:将年、月、日拼接为yyyy-MM-dd格式 NSMutableArray *finalResult = [NSMutableArray array]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @"yyyy-MM-dd"; for (NSDictionary *item in results) { NSDateComponents *comps = [[NSDateComponents alloc] init]; comps.year = [item[@"year"] integerValue]; comps.month = [item[@"month"] integerValue]; comps.day = [item[@"day"] integerValue]; NSDate *date = [[NSCalendar currentCalendar] dateFromComponents:comps]; [finalResult addObject:@{ @"start": [formatter stringFromDate:date], @"count": item[@"count"] }]; }
说明
- 该方案使用Core Data标准支持的
extract函数提取日期分量,兼容所有Core Data存储后端,查询效率高 - 如果你需要按指定时区计算日期,只需要在创建
NSCalendar和NSDateComponents时设置对应时区即可 - 最终得到的
finalResult就是你需要的按纯日期合并后的统计结果
内容的提问来源于stack exchange,提问作者Paras Saini
相关产品推荐
相关产品推荐

