Search code examples
objective-cios5xcode4.2

Count the number of Leap Year Days in a temporal difference in xcode


I'm trying to determine the number of leap year days between two different dates for an app that goes back to the 19thC - here is a method example:

-(NSInteger)leapYearDaysWithinEraFromDate:(NSDate *) startingDate toDate:(NSDate *) endingDate {

// this is for testing - it will be changed to a datepicker object
NSDateComponents *startDateComp = [[NSDateComponents alloc] init];
[startDateComp setSecond:1];
[startDateComp setMinute:0];
[startDateComp setHour:1];
[startDateComp setDay:14];
[startDateComp setMonth:4];
[startDateComp setYear:2005];

NSCalendar *GregorianCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

//startDate declared in .h//
startDate = [GregorianCal dateFromComponents:startDateComp];
NSLog(@"This program's start date is %@", startDate);


NSDate *today = [NSDate date];
NSUInteger unitFlags = NSDayCalendarUnit;
NSDateComponents *temporalDays = [GregorianCal components:unitFlags fromDate:startDate toDate:today options:0];

NSInteger days = [temporalDays day];

// then i will need code for the number of leap year Days

return 0;//will return the number of 2/29 days

}

So I have the number of TOTAL days between the dates. Now I need to subtract the number of leap year days???

PS - I know there are two leap year days in this example but the app will go back to the 19th century...


Solution

  • Ok, well, you are overcomplicating this. I think this is what you want:

    NSUInteger leapYearsInTimeFrame(NSDate *startDate, NSDate *endDate)
    {
        // check to see if it's possible for a leap year (e.g. endDate - startDate > 1 year)
        if ([endDate timeIntervalSinceDate:startDate] < 31556926)
            return 0;
    
        // now we go year by year
        NSUInteger leapYears = 0;
        NSUInteger startYear = [[NSCalendar currentCalendar] components:NSYearCalendarUnit fromDate:startDate].year;
        NSUInteger numYears = [[NSCalendar currentCalendar] components:NSYearCalendarUnit fromDate:endDate].year - startYear;
    
        for (NSUInteger currentYear = startYear; currentYear <= (startYear + numYears); currentYear++) {
            if (currentYear % 400 == 0)
                // divisible by 400 is a leap year
                leapYears++;
            else if (currentYear % 100 == 0)
                /* not a leap year, divisible by 100 but not 400 isn't a leap year */ 
                continue;
            else if (currentYear % 4 == 0)
                // divisible by 4, and not by 100 is a leap year
                leapYears++;
            else 
                /* not a leap year, undivisble by 4 */
                continue;
        }
    
        return leapYears;    
    }