pedroremedios pedroremedios - 1 year ago 62
iOS Question

Elapsed days between two dates always giving one days difference

I'm trying to work out the number of days between two dates. Here is how I am doing it:

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

unsigned int calendarFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDate *dateToCheck = (self.subscriptionEnd ?: self.trialEnd);
NSLog(@"dateToCheck: %@", dateToCheck);
NSLog(@"current date: %@", [self systemTimeZoneDate]);
NSDateComponents *components = [gregorian components:calendarFlags
fromDate:[self systemTimeZoneDate]
return [components day] >= 0 ?: 0;

At the time of this writing, NSLog outputted the following:

2014-09-05 22:56:20.054 tweepy[9635:60b] dateToCheck: 2014-10-05 08:02:51 PM +0000
2014-09-05 22:56:20.057 tweepy[9635:60b] current date: 2014-09-05 10:56:20 PM +0000

It is returning a difference of one day because iOS thinks that the day is in YDM format.

Should I be indicating the date format somewhere?

Here is the code of how
is setup:

NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; = 30;
self.subscriptionEnd = [gregorianCalendar dateByAddingComponents:dateComponents toDate:[self systemTimeZoneDate] options:0];

Here is the code of how
is setup:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; = 2;
self.trialEnd = [gregorian dateByAddingComponents:dateComponents toDate:[self systemTimeZoneDate] options:0];

Answer Source

The date format doesn't have anything to do with it. What is happening is the NSDateComponents are giving you what you are asking for, the total difference in years, months, and days. If you want just the days, you need to only provide NSDayCalendarUnit. The docs make this clear:

Some operations can be ambiguous, and the behavior of the computation is calendar-specific, but generally larger components will be computed before smaller components; for example, in the Gregorian calendar a result might be 1 month and 5 days instead of, for example, 0 months and 35 days.