如何计算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开始,您可以使用NSCalendar
的startOfDayForDate
我在我的一个应用程序中有同样的问题,我从来没有find一个谓词来做到这一点。
我目前正在查看实体中的所有对象,并计算每个date的date,然后返回一个唯一天数组。 我正在考虑为我的实体添加一个date属性,但尚未testing该概念。
以下是我目前使用的代码。 注意:
- 这两种方法都是类
Game
中的类方法 - 我的模型中的实体被称为
Game
,我想要转换为独特的天的属性是startDateTime
- 返回的数组包含反向sorting顺序中的唯一天数(最近一天)
- 如果你不关心实际的独特的日子,但只有独特的天数计数是微不足道的改变返回天数(
[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);