如何计算CoreData对象的唯一date?

我需要一个正确的方法来计算CoreData对象有一个NSDatetypes属性的独特天数。

例如,我有以下几点:

<Object>.date = "2014-05-15 21:29:12 +0000"; <Object>.date = "2014-05-15 21:49:34 +0000"; <Object>.date = "2014-05-16 13:29:23 +0000"; <Object>.date = "2014-05-16 20:49:50 +0000"; <Object>.date = "2014-05-16 22:01:53 +0000"; <Object>.date = "2014-05-20 03:32:12 +0000"; <Object>.date = "2014-05-20 12:45:23 +0000"; <Object>.date = "2014-05-20 14:15:50 +0000"; <Object>.date = "2014-05-20 20:20:05 +0000"; 

在这种情况下,结果必须是3,因为2014-05-15,2014-05-16和2014-05-20有3天

任何方式来处理这个问题? 我尝试了NSPredicate,但是没有成功

谢谢!

这很容易。 让我告诉你我要为它做些什么。

用sorting描述键对结果进行分组。 这个例子可以帮助你理解如何实现。

https://developer.apple.com/library/ios/samplecode/DateSectionTitles/Introduction/Intro.html

然后只计算这些组。

编辑:

的NSDate + Utils.h

 - (NSDate *) dateWithoutTime 

的NSDate + Utils.m

 -(NSDate *) dateWithoutTime { NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:self]; return [calendar dateFromComponents:components]; } 

一些文件

 - (NSUInteger) someObjectsCount { NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"]; NSString *key = @"date.dateWithoutTime"; fetchRequest.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:key ascending:YES]]; NSManagedObjectContext *context; context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; NSFetchedResultsController *aFetchedResultsController; aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:key cacheName:nil]; [aFetchedResultsController performFetch:nil]; return [[aFetchedResultsController sections] count]; } 

就这样!

从iOS 8开始,您可以使用NSCalendarstartOfDayForDate

我在我的一个应用程序中有同样的问题,我从来没有find一个谓词来做到这一点。

我目前正在查看实体中的所有对象,并计算每个date的date,然后返回一个唯一天数组。 我正在考虑为我的实体添加一个date属性,但尚未testing该概念。

以下是我目前使用的代码。 注意:

  1. 这两种方法都是类Game中的类方法
  2. 我的模型中的实体被称为Game ,我想要转换为独特的天的属性是startDateTime
  3. 返回的数组包含反向sorting顺序中的唯一天数(最近一天)
  4. 如果你不关心实际的独特的日子,但只有独特的天数计数是微不足道的改变返回天数( [uniqueDays count]

我的代码:

 + (NSArray *)allGameStartDaysInManagedObjectContext:(NSManagedObjectContext *)moc { __block NSArray *gameDates; // mod cannot be nil NSParameterAssert(moc); [moc performBlockAndWait:^{ NSError *error; NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Game"]; NSArray *game = [moc executeFetchRequest:request error:&error]; // Check for errors if (!game) { // Log errors NSLog(@"[%@ %@ %d]", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__); NSLog(@"Core Data error: %@", error.localizedDescription); NSArray *errors = [[error userInfo] objectForKey:NSDetailedErrorsKey]; if (errors != nil && errors.count > 0) { for (NSError *error in errors) { NSLog(@" Error: %@", error.userInfo); } } else { NSLog(@" %@", error.userInfo); } gameDates = nil; } else if (game.count) { // Array to hold (at most) all the days of the games in the database NSMutableArray *days = [[NSMutableArray alloc] initWithCapacity:game.count]; for (Game *games in game) { // Add only the day to the array [days addObject:[Game convertDateTimetoDay:games.startDateTime]]; } // Generate a unique set of dates NSSet *uniqueDays = [NSSet setWithArray:days]; // Create an array from the unique set NSMutableArray *uniqueGameDays = [NSMutableArray arrayWithArray:[uniqueDays allObjects]]; // Create the sort descriptor NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO]; // Sort the array NSArray *sortedUniqueGameDays = [uniqueGameDays sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortOrder]]; gameDates = [sortedUniqueGameDays copy]; } else { gameDates = nil; } }]; return gameDates; } + (NSDate *)convertDateTimetoDay:(NSDate *)dateTimeToConvert { // Get the year, month and day components (included era although this only applies to BCE) NSDateComponents *components = [[NSCalendar currentCalendar] components:NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:dateTimeToConvert]; // Add the date with only the selected components to the array return [[[NSCalendar currentCalendar] dateFromComponents:components] dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]]; } 

您应该拥有一个名为“daydate”的新属性,它是从当前date和时间设置为午夜的date。

每当你创build/修改你的一个对象,就像这样操作:

 NSDate *date = [NSDate date]; NSCalendar *calendar = [NSCalendar currentCalendar]; [calendar setTimeZone:[NSTimeZone systemTimeZone]]; NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date]; NSDate *daydate = [calendar dateFromComponents:dateComps]; myObject.date = date; myObject.daydate = daydate; 

然后你可以操作你的获取(2选项)。

选项1:

 NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"myObject" inManagedObjectContext:self.managedObjectContext]; [request setEntity:entity]; NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"daydate"]; NSExpression *functionExpression = [NSExpression expressionForFunction:@"count:" arguments:@[keyPathExpression]]; NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@"count for this daydate:"]; [expressionDescription setExpression:functionExpression]; [expressionDescription setExpressionResultType:NSDoubleAttributeType]; NSAttributeDescription *attributeDesc = (entity.attributesByName)[@"daydate"]; [request setPropertiesToFetch:@[attributeDesc, expressionDescription]]; [request setPropertiesToGroupBy:@[attributeDesc]]; [request setResultType:NSDictionaryResultType]; NSError *error = nil; NSArray *array = [self.managedObjectContext executeFetchRequest:request error:&error]; NSLog(@"array: %@", array); NSLog(@"%lu", (unsigned long)array.count); 

选项2:

 NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"myObject" inManagedObjectContext:self.managedObjectContext]; [request setEntity:entity]; request.returnsDistinctResults = YES; request.propertiesToFetch = @[@"daydate"]; request.resultType = NSDictionaryResultType; NSError *error = nil; NSArray *array = [self.managedObjectContext executeFetchRequest:request error:&error]; NSLog(@"array: %@", array); NSLog(@"array count: %lu", (unsigned long)array.count);