Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating the end of a month, or its last second

I have the simplest of tasks that I can't figure out how to do correctly. With the snippet below I can find out the beginning of a month.

NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *beginning = nil;
[cal rangeOfUnit:NSMonthCalendarUnit startDate:&beginning interval:NULL forDate:self];
return beginning;

Now I want to determine the end of that same month (the last second at 23:59:59 would suit my purposes). My first thought was to start at the first day of the next month and subtract a second. But I couldn't break down the date in an NSDateComponent instance to [dateComponents setMonth:[dateComponents month] + 1], because in the case of December that method wouldn't accept 12 + 1 = 13 to get to January, right?

Then how would I get to the last second of a month?

like image 443
epologee Avatar asked Jun 05 '11 20:06

epologee


2 Answers

Do this to get the beginning of next month:

NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setMonth:1];
NSDate *beginningOfNextMonth = [cal dateByAddingComponents:comps toDate:beginning options:0];
[comps release];
like image 116
spacehunt Avatar answered Sep 19 '22 18:09

spacehunt


Alright, I think I have it. I'm using the rangeOfUnit:inUnit:forDate: method to determine the length of the current month in days, and add the corresponding NSTimeInterval to the month's start date.

- (NSDate *)firstSecondOfTheMonth {
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDate *beginning = nil;
    if ([cal rangeOfUnit:NSMonthCalendarUnit startDate:&beginning interval:NULL forDate:self])
        return beginning;
    return nil;
}

- (NSDate *)lastSecondOfTheMonth {
    NSDate *date = [self firstSecondOfTheMonth];
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSRange month = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
    return [date dateByAddingTimeInterval:month.length * 24 * 60 * 60 - 1];
}

Note: Although this code works as I intended it to work, the answer that @spacehunt gave more clearly communicates the purpose.

like image 38
epologee Avatar answered Sep 17 '22 18:09

epologee