I'm trying to perform date calculations for a scheduling app but am running into issues with daylight savings time. I'm trying to determine the number of days between two dates with:
NSDateComponents *activityComponents = [[NSDateComponents alloc]init];
activityComponents = [self.calendar components:NSDayCalendarUnit
fromDate:self.viewBeginDate
toDate:item.ES
options:0];
NSLog(@"Days: %d and hours: %d", [activityComponents day], [activityComponents hour]);
where self.viewBeginDate
and item.ES
are both NSDate objects and self.calendar
is a gregorian calendar.
Here is my output:
Days: 0 and hours: 0
Days: 1 and hours: 0
Days: 2 and hours: 0
Days: 2 and hours: 24
Days: 3 and hours: 23
I'd like to be able to determine the number of days between 2 NSDate
objects without impact by Daylight Savings Time, as my app doesn't care what local or timezone the user is in. I just want it to tell me that there are 3 days between Nov 1, 2013 and Nov 4, 2013. Any thoughts?
My NSDate
objects are created from strings in the format of: 2013-11-01 00:00:00 +0000. Each date has the time set to 00:00:00 with the GMT offset of +0000.
I've thought of two possible options:
isDaylightSavingTime
to check each date and create a new (modified) date offset by 1 hour if it the date is Daylight Savings Time. I'm worried about the added calculation time as my app calculates the date between a given begin date and an array of other dates. This array may have up to 2,000 dates in it. I'm not sure if that's a legit concern or not...I can confirm your observations using dates around the 27 October (when British Summer Time started) and setting the time zone to Europe/London. The "n days 24 hours" seems to be a quirk (kind word for a bug, somebody forgot to carry).
Solution 1: Use an NSCalendar
set to UTC. UTC has no daylight savings.
Solution 2: As all your times are at midnight and the maximum daylight savings shift is 1 hours then a "day" is between 23 and 25 hours. To allow for this, and handle the quirk at the same time simply:
daysBetween = [activityComponents day] + ([activityComponents hour] >= 23 ? 1 : 0);
Note that this only works because time is the same in the two dates!