Is there a better way to do this?
-(NSDate *)getMidnightTommorow {
NSCalendarDate *now = [NSCalendarDate date];
NSCalendarDate *tomorrow = [now dateByAdd
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:(24 * 60 * 60)];
NSDateComponents *components = [gregorian components:(NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit)
fromDate:tomorrow];
NSDate *midnight = [gregorian dateFromComponents:components];
[NSDate dateWithNaturalLanguageString:@"midnight tomorrow"];
You could try this way:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:1];
NSDate *tomorrow = [calendar dateByAddingComponents:comps toDate:[NSDate date] options:0]; //it gives us tomorrow with current time
NSDate *midnight = [calendar startOfDayForDate:tomorrow]; //here we get next midnight
It is also easy to retrieve the seconds interval if needed to set up an NSTimer:
double intervalToMidnight = midnight.timeIntervalSinceNow;
Nope - it'll be the same way you use to find midnight today.
From the documentation:
Use of NSCalendarDate strongly discouraged. It is not deprecated yet, however it may be in the next major OS release after Mac OS X v10.5. For calendrical calculations, you should use suitable combinations of NSCalendar, NSDate, and NSDateComponents, as described in Calendars in Dates and Times Programming Topics for Cocoa.
Following that advice:
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.day = 1;
NSDate *tomorrow = [gregorian dateByAddingComponents:components toDate:today options:0];
[components release];
NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
components = [gregorian components:unitFlags fromDate:tomorrow];
components.hour = 0;
components.minute = 0;
NSDate *tomorrowMidnight = [gregorian dateFromComponents:components];
[gregorian release];
[components release];
(I'm not sure offhand if this is the most efficient implementation, but it should serve as a pointer in the right direction.)
Note: In theory you can reduce the amount of code here by allowing a date components object with values greater than the range of normal values for the component (e.g. simply adding 1 to the day component, which might result in its having a value of 32). However, although dateFromComponents:
may tolerate out-of-bounds values, it's not guaranteed to. You're strongly encouraged not to rely on it.
Convert your current date and time to a Unix date (seconds since 1970) or DOS style (since 1980), then add 24 hours and convert it back. Then reset the hours, minutes and seconds to zero to get to midnight.