Yes, this is similar to NSDate beginning of day and end of day, but that topic does not discuss whether it works for all situations which is what I am asking here. That question dealt with not getting back the correct value because they forgot NSDayCalendarUnit. This question is dealing with the accuracy of the value which as it turns out is not going to work with DST as I had suspected.
In several parts of my app, I have the need to specify a time of day without caring about the actual day, e.g., do this activity at 4:00pm every day. I have seen a few posts that talk about how to do this, but would like feedback on my approach. The method below is intended to return midnight of any particular day and will be used in conjunction with an offset that represents the number of seconds to a particular time (for instance, 1:00:00 am as 3600).
I believe it should work, but am curious if it will handle edge cases such as daylight savings time. Any feedback would be appreciated. Thanks!
// We want to return 12:00:00AM of the day represented by the time interval
NSTimeInterval getStartOfDay(NSTimeInterval t)
{
// first convert the time interval to an NSDate
NSDate *ourStartingDate = [NSDate dateWithTimeIntervalSinceReferenceDate:t] ;
// get just the year, month, and day of our date
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:unitFlags fromDate:ourStartingDate];
NSDate *ourConvertedDate = [gregorian dateFromComponents:comps] ;
// put that date into a time interval
NSTimeInterval convertedInterval = [ourConvertedDate timeIntervalSinceReferenceDate] ;
// because the time interval is in GMT and we may not be, we need to get an offset
NSInteger timeZoneOffset = [[NSTimeZone localTimeZone ] secondsFromGMT] ;
// account for the time zone difference
convertedInterval = convertedInterval - timeZoneOffset ;
// still might have a Daylight Savings Time issue?
return convertedInterval ;
}
This will not handle edge cases. In Brazil, DST either eliminates or duplicates the midnight-to-one-AM hour. So on some days, there is no midnight, and on others there are two midnights.
The correct way to handle this is to either make your own data type representing a time of day (independent of date), or to use
NSDateComponents
, setting only the time-of-day components.If you want to represent a date, independent of a time-of-day, you're better off using noon of that day than using midnight. Or you can create your own data type, or use
NSDateComponents
, storing only day/month/year/era.I highly recommend you watch these WWDC videos ASAP: