I'm having a hard time understanding an exception to how dateByAddingComponents handles Daylight Savings. I've read through the Apple Date and Time Programming Guide and expected dateByAddingComponents to take into account DST changes. However, on the date of the DST change, its not working for me.
Here's the code:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *midnight = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self.currentDate];
midnight.hour = 0;
midnight.minute = 0;
midnight.second = 0;
NSDate *startDate = [gregorian dateFromComponents:midnight];
NSDateComponents *offSetComponents = [[NSDateComponents alloc] init];
[offSetComponents setDay:1];
NSDate *endDate = [gregorian dateByAddingComponents:offSetComponents toDate:startDate options:0];
//Calculate start time from config (hours/min from seconds)
int startTimeInMinutes = self.club.clubConfiguration.startTime.integerValue;
int startTimeHours = startTimeInMinutes / 60;
int startTimeMins = startTimeInMinutes % 60;
NSLog(@"---- startTimeHours %i", startTimeHours);
NSLog(@"---- startTImeMins %i", startTimeMins);
NSDateComponents *offSetComponents2 = [[NSDateComponents alloc] init];
[offSetComponents2 setHour:startTimeHours];
[offSetComponents2 setMinute:startTimeMins];
NSDate *firstTeeTime = [gregorian dateByAddingComponents:offSetComponents2 toDate:startDate options:0];
Explanation: I'm getting a startTimeInMinutes from the server that I use to calculate the firstTeeTime. For example, I'm expecting to add 6 hours to the startDate (12am in my use case) and get 6am (localTimeZone).
Using dateByAddingComponents works both before and after the DST change however, on the day of DST change Sunday Nov 3, I'm getting 5am.
Theory: Since there are actually 2 2am's on Sunday Nov 3rd, I may have to account for that? If thats the case, I'd have to write some logic to account for the actual day of DST change and add an offset if appropriate using daylightSavingTimeOffsetForDate.
What am I missing???
EDIT: Ok, I decided to work around the issue by determining if today was the DST change and add/remove an hour offset. Feels kinda like I'm missing something here about NSDate however, it works. Hope this helps someone else out there scratching their heads all morning.
Work Around Code:
////// Work around for DST
NSTimeZone *currentZone = [gregorian timeZone];
NSDate *dstTransitionDate = [currentZone nextDaylightSavingTimeTransitionAfterDate:startDate];
NSTimeInterval dstOffset = [currentZone daylightSavingTimeOffsetForDate:endDate];
NSDateComponents *startDateComponents = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:startDate];
NSDateComponents *dstTransitionDateComponents = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:dstTransitionDate];
int offset = 0;
if ( [startDateComponents year] == [dstTransitionDateComponents year] &&
[startDateComponents month] == [dstTransitionDateComponents month] &&
[startDateComponents day] == [dstTransitionDateComponents day])
{
if (dstOffset > 0){
offset = -1;
} else {
offset = 1;
}
}
//////