What's the best/easiest way to compare two times in Objective-C?
I've got a string representation of a time, like "11:13 AM." This was produced using an NSDateFormatter and the stringFromDate: method.
I'd like to compare this time to the current time, but when I use the dateFromString: method to turn the string back into a date, a year, month and day are added - which I don't want. I just need to know if right now is < or > the time stored in the string.
What开发者_运维百科's going to be the best way to handle that? Thanks in advance for your help.
Instead of using the string representation, use the NSDate you got from the picker. You can convert that hour/min/sec using NSDateComponents, then also convert [NSDate date] to NSDateComponents. Compare the hours/minutes/seconds of the two sets of components.
EDIT -- use a utility function for things like this that converts the hr/min/sec components of NSDate into a secondsOfTheDay (seconds since midnight).
You can directly use two time of day values since they are both seconds since midnight. Simple integers can be easily compared and stored and manipulated. You don't have to use NSDate all the time.
//----------------------------------------------------------------------------
// extracts hour/minutes/seconds from NSDate, converts to seconds since midnight
//----------------------------------------------------------------------------
unsigned secondOfTheDay( NSDate* time )
{
NSCalendar* curCalendar = [NSCalendar currentCalendar];
const unsigned units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents* comps = [curCalendar components:units fromDate:time];
int hour = [comps hour];
int min = [comps minute];
int sec = [comps second];
return ((hour * 60) + min) * 60 + sec;
}
If I understand the problem correctly, you’re using the dateFromString:
method of NSDateFormatter
. This is giving you the correct time, but with a default date of January 1, 1970, which is useless to compare against the current date/time.
This is easy to solve. Use setDefaultDate:
to set the default date to today.
NSDate *now = [NSDate date];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:@"hh:mm a"];
[formatter setDefaultDate:now];
NSDate *theDate = [formatter dateFromString:@"11:13 AM"];
NSComparisonResult theResult = [theDate compare:now];
Can you reuse the string formatter that you used to create the string? So, let's say you created the string like this:
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init];
[formatter setDateFormat:@"HH:mm a"];
NSString *dateAsString = [formatter stringFromDate:[NSDate date]];
You can get an NSDate like this:
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init];
[formatter setDateFormat:@"HH:mm a"];
NSDate *date = [formatter dateFromString:dateAsString];
The day, month, year and timezone information will not be kept, but you'll have an NSDate object with the values of 1/1/1970 and GMT for the timezone offset.
At this point you can use the compare: (which is typically reserved for sorting operations) or the laterDate: or earlierDate: methods.
Be careful using NSDateFormatter like this, as you may run into issues with internationalization.
If you need to add information about the current date to the date you get from dateFromString:, such as the month day and year, you'll need to use NSCalendar's dateByAddingComponents:toDate:options: method.
If the string was originally created from an NSDate
, then you'll want to use that original NSDate
to compare against [NSDate date]
using NSDate
's compare:
method (or some variant, such as earlierDate:
or laterDate:
).
You should use 24-hour based NSDateFormatter and compare as strings ("09:00am" > "08:00pm", but "09:00" < "20:00") . But in general it is right to operate with NSDate instances instead of strings
精彩评论