Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Check if an NSDate occurs between two other NSDates

I am trying to figure out whether or not the current date falls within a date range using NSDate.

For example, you can get the current date/time using NSDate:

NSDate rightNow = [NSDate date]; 

I would then like to use that date to check if it is in the range of 9AM - 5PM.

like image 521
Brock Woolf Avatar asked Jul 02 '09 06:07

Brock Woolf


2 Answers

I came up with a solution. If you have a better solution, feel free to leave it and I will mark it as correct.

+ (BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {     if ([date compare:beginDate] == NSOrderedAscending)         return NO;      if ([date compare:endDate] == NSOrderedDescending)          return NO;      return YES; } 
like image 65
Brock Woolf Avatar answered Nov 09 '22 01:11

Brock Woolf


For the first part, use the answer from @kperryua to construct the NSDate objects you want to compare with. From your answer to your own question, it sounds like you have that figured out.

For actually comparing the dates, I totally agree with @Tim's comment on your answer. It's more concise yet actually exactly equivalent to your code, and I'll explain why.

+ (BOOL) date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {     return (([date compare:beginDate] != NSOrderedAscending) && ([date compare:endDate] != NSOrderedDescending)); } 

Although it may seem that the return statement must evaluate both operands of the && operator, this is actually not the case. The key is "short-circuit evaluation", which is implemented in a wide variety of programming languages, and certainly in C. Basically, the operators & and && "short circuit" if the first argument is 0 (or NO, nil, etc.), while | and || do the same if the first argument is not 0. If date comes before beginDate, the test returns NO without even needing to compare with endDate. Basically, it does the same thing as your code, but in a single statement on one line, not 5 (or 7, with whitespace).

This is intended as constructive input, since when programmers understand the way their particular programming language evaluates logical expressions, they can construct them more effectively without so much about efficiency. However, there are similar tests that would be less efficient, since not all operators short-circuit. (Indeed, most cannot short-circuit, such as numerical comparison operators.) When in doubt, it's always safe to be explicit in breaking apart your logic, but code can be much more readable when you let the language/compiler handle the little things for you.

like image 21
Quinn Taylor Avatar answered Nov 09 '22 02:11

Quinn Taylor