furins
furins

Reputation: 5048

Retrieve the next day not included in a CoreData request result

I would like to get the next available day by starting my search from today and excluding the dates provided by a Core Data request.

my initialization code, and a helping method implemented in the same class

+ (NSDate *)getDateByAddingDays:(NSInteger)days toDate:(NSDate *)date {
    NSDate *newdate = [[NSDate alloc]init];
    if (days != 0) {
        NSDateComponents *components = [[NSDateComponents alloc] init];
        components.day = days;
        NSCalendar *calendar = [NSCalendar currentCalendar];
        newdate = [calendar dateByAddingComponents:components toDate:date
                                           options:0];
    }
    return newdate;
}

+ (void)myTroublesomeMethod {

    // standard initialization of NSFetchRequest
    NSManagedObjectContext *context = [(id)[[UIApplication sharedApplication] delegate] managedObjectContext];

    NSDate *today = [NSDate date];

    NSFetchRequest *request3 = [[NSFetchRequest alloc] init];
    NSEntityDescription *chiusureDescription = [NSEntityDescription entityForName:@"Chiusure" inManagedObjectContext:context];
    NSError *error;
    [request3 setEntity:chiusureDescription];
    NSArray *arrayChiusure = [context executeFetchRequest:request3 error:&error];

    // I then extract the "data" attribute, that stores the date to be excluded

    NSMutableArray *giorniChiusura = [[NSMutableArray alloc]init];
        for (Chiusure *entity in arrayChiusure) {
            [giorniChiusura addObject:(NSDate*) entity.data];
        }

    // and here is where the problem rises:

    NSInteger days = 0;
    NSDate *nextDate = [self getDateByAddingDays:days toDate:today];
    if ([arrayChiusure containsObject:nextDate]) {

        // HERE is the error, I suppose. nextDate is never contained in arrayChiusure, so the next while statement is an infinite loop.

        while ([arrayChiusure containsObject:nextDate]) {
            days += 1;
            nextDate = [self getDateByAddingDays:days toDate:today];
        }

    // OMITTED: use of nextDate somewhere later in my code
}

ALTERNATIVE APPROACHES I'VE THOUGHT AT:

ADDITIONAL INFO:

any help is appreciated :) thanks in advance

Upvotes: 0

Views: 86

Answers (1)

Martin R
Martin R

Reputation: 539715

As already mentioned in a comment, the problem is that NSDate represents not only the day, but also the time up to milli-seconds. Therefore you have to "normalize" the date first to represent the current day at midnight (or whatever is store in the Core Data objects).

However, there is an easier solution: You can create a fetch request that returns only the most recent date already present in the store (see https://stackoverflow.com/a/18395185/1187415 for an example) and then add one day to it.

Example:

NSArray *arrayChiusure = [context executeFetchRequest:request3 error:&error];

// Extract "data" attribute into new array:
NSArray *giorniChiusura = [arrayChiusure valueForKey:@"data"];

// nextDate = "today at midnight":
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *today = [NSDate date];
NSDate *nextDate;
[calendar rangeOfUnit:NSDayCalendarUnit startDate:&nextDate interval:NULL forDate:today];

// Find next available day:
NSDateComponents *oneDay = [[NSDateComponents alloc]init];
oneDay.day = 1;
while ([giorniChiusura containsObject:nextDate]) {
    nextDate = [calendar dateByAddingComponents:oneDay toDate:nextDate options:0];
}

Upvotes: 1

Related Questions