NSDate -dateWithNaturalLanguageString: on iPhone?
-
20-09-2019 - |
Question
In the iPhone docset for NSDate, in the discussion area they discuss -dateWithNaturalLanguageString:locale:
, however they don't document the method elsewhere on the page.
I've used the method before for iPhone and it worked just fine, although I got warnings. Now that I'm building with -Werror
(which I should have been doing all along ^_^) I've run into a warning with this.
How would I replace the following lines of code?
NSDate *today = [NSDate dateWithNaturalLanguageString:@"today at 23:59:59"];
NSDate *tomorrow = [NSDate dateWithNaturalLanguageString:@"tomorrow at 23:59:59"];
Solution
One way to do this is with NSCalendar and NSDateComponents.
To get today at 23:59:59:
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit
fromDate:date];
[comps setHour:23];
[comps setMinute:59];
[comps setSecond:59];
NSDate *today = [calendar dateFromComponents:comps];
To get tomorrow at 23:59:59:
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:24 * 60 * 60]; // 24h from now
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit
fromDate:date];
[comps setHour:23];
[comps setMinute:59];
[comps setSecond:59];
NSDate *tomorrow = [calendar dateFromComponents:comps];
OTHER TIPS
Let's assume:
static const unsigned long seconds_per_day = 60 * 60 * 24;
You can get now and now+24 hours with:
NSDate* today = [NSDate date]; // set for today
NSDate* tomorrow = [today addTimeInterval:seconds_per_day];
In order to get midnight for the given day, it's important to remember that NSDate*
is toll-free bridged to CFDateRef
, which provides some additional APIs you'll want to use. In particular, you can convert an NSDate
to a CFAbsoluteTime
with CFDateGetAbsoluteTime
:
CFAbsoluteTime abstime = CFDateGetAbsoluteTime(reinterpret_cast<CFDateRef>(myNSDate));
long long inttime = static_cast<long long>(abstime);
inttime = (inttime / seconds_per_day) * seconds_per_day; // clips the time to midnight
NSDate* myNSDateAtMidnight = reinterpret_cast<NSDate*>(CFDateCreate(NULL,
static_cast<CFAbsoluteTime>(inttime)));
... which you can wrap into a function to round both today
and tomorrow
to midnight.