0
NSDateComponents *components;
components = [[NSCalendar currentCalendar] components: NSDayCalendarUnit
                                             fromDate: startDate 
                                               toDate: endDate options: 0];
days = [components day];

That code seems to create some issue calculating the exact difference between dates: is it possible ???

I'm thinking to use gregorian calendar instead ... how ?

Fabrizio
  • 183
  • 1
  • 12
  • The best way to get help here would be to provide an example of what you expect to get as an answer, and what you are actually getting. Include all data (like startDate and endDate) that we need to have in order to duplicate your issue. – lnafziger Nov 30 '12 at 23:43
  • Here's a log: Start Date: 2010-10-01 00:00:00 +0000 End Date: 2010-12-31 00:00:00 +0000 Days: 90 Should be 92 days, isn't it ? Any idea from that log ? – Fabrizio Nov 30 '12 at 23:49
  • Probably i need to include StartDate and EndDate to have 92 days ? – Fabrizio Nov 30 '12 at 23:50
  • Yes, if you want them to be included. There are 90 days **from** 10/1/10 **to** 12/31/10.... – lnafziger Dec 01 '12 at 04:45
  • and how to include also startDate and EndDate in these cases ? – Fabrizio Dec 01 '12 at 09:08

1 Answers1

4

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
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"] should give the same results ? – Fabrizio Dec 01 '12 at 12:48
  • @Fabrizio:I strongly assume so. But I am not an expert on the subtle differences between GMT and UTC, so you might do your own research to verify this. [Coordinated Universal Time](http://en.wikipedia.org/wiki/Coordinated%5FUniversal%5FTime) from Wikipedia states: "For most purposes, UTC is synonymous with GMT, but GMT is no longer precisely defined by the scientific community." – Martin R Dec 01 '12 at 13:49