First of all, components:fromDate:toDate
returns the difference between the two dates. So one would expect 91 days for the difference from 2010-10-01 to 2010-12-31, and you have to add one day to include both start date and end date.
The question is: Why does the function return 90 days instead of 91?
The problem lies in the time zone used by the calendar and thus by the date components. By default, the local time zone is used. Let us assume for example that the local time zone is "Europe/Berlin".
Then the start date is "2010-10-01 02:00:00" in the local time zone, because daylight savings time is active at the beginning of October, and the end date is 2010-12-31 01:00:00 in the local time zone, because daylight savings time is not active in December. And the difference between those two dates is 90 days and 23 hours, not 91 days!
To solve the problem, you can either
- create the start and end date according to your local time zone, or
- set the time zone to "GMT" for the difference calculation.
Example for the second solution:
// Create start and end date as in your example:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSDate *startDate = [dateFormatter dateFromString:@"2010-10-01"];
NSDate *endDate = [dateFormatter dateFromString:@"2010-12-31"];
NSLog(@"start=%@", startDate);
NSLog(@"end =%@", endDate);
// Output:
// start=2010-10-01 00:00:00 +0000
// end =2010-12-31 00:00:00 +0000
// Compute difference according to GMT:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDateComponents *components;
components = [gregorian components: NSDayCalendarUnit
fromDate: startDate
toDate: endDate
options: 0];
int days = [components day];
// --> days = 91