12

When my app is launched I want to check whether the date is between 9:00-18:00.

And I can get the time of now using NSDate. How can I check the time?

j0k
  • 22,600
  • 28
  • 79
  • 90
Relex
  • 123
  • 4

2 Answers2

19

So many answers and so many flaws...

You can use NSDateFormatter in order to get an user-friendly string from a date. But it is a very bad idea to use that string for date comparisons!
Please ignore any answer to your question that involves using strings...

If you want to get information about a date's year, month, day, hour, minute, etc., you should use NSCalendar and NSDateComponents.

In order to check whether a date is between 9:00 and 18:00 you can do the following:

NSDate *date = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [calendar components:NSHourCalendarUnit fromDate:date];

if (dateComponents.hour >= 9 && dateComponents.hour < 18) {
    NSLog(@"Date is between 9:00 and 18:00.");
}

EDIT:
Whoops, using dateComponents.hour <= 18 will result in wrong results for dates like 18:01. dateComponents.hour < 18 is the way to go. ;)

Fabian Kreiser
  • 8,307
  • 1
  • 34
  • 60
6

Construct dates for 09:00 and 18:00 today and compare the current time with those dates:

NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *now = [NSDate date];
NSDateComponents *components = [cal components:NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];

[components setHour:9];
[components setMinute:0];
[components setSecond:0];
NSDate *nineHundred = [cal dateFromComponents:components];

[components setHour:18];
NSDate *eighteenHundred = [cal dateFromComponents:components];

if ([nineHundred compare:now] != NSOrderedDescending &&
    [eighteenHundred compare:now] != NSOrderedAscending)
{
    NSLog(@"Date is between 09:00 and 18:00");
}
Fabian Kreiser
  • 8,307
  • 1
  • 34
  • 60
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • Hi guys, thanks for your ways, I understand what you means , but the nineHundred and eighteenHundred is nil,I think I can fix the bug, thankyou for your method – Relex Feb 22 '13 at 08:33
  • @Relex And what is the fix required? Please update my answer as this is the best way to construct dates necessary for comparison. – trojanfoe Feb 22 '13 at 09:00
  • Thank you! This is the only answer that's using `NSCalendar` to do the comparison. There's still hope. Constructing the two dates for the comparison isn't necessary, though. You can check if the component's `hour` property is between 9 and 18 directly. Also, the week, weekday, timezone calendar units aren't required. – Fabian Kreiser Feb 22 '13 at 09:45
  • @trojanfoe In some situations constructing dates for the comparison can be better, so your code isn't bad at all. But for this simple check it's a little bit overkill. ;) – Fabian Kreiser Feb 22 '13 at 09:56
  • Ahh, please don't remove your code! It's quite convenient when you want to check whether a date is between two absolute dates like February, 21 2013 8:32am and February, 22 2013 9:32 am or something similar. – Fabian Kreiser Feb 22 '13 at 09:59
  • @FabianKreiser Apparently it wasn't working though (the dates were `nil`) as I did it from the manual without testing. Can you suggest why they would be `nil`? – trojanfoe Feb 22 '13 at 10:02
  • @trojanfoe your date is nil because you did not set the calendar , add this code [components setCalendar:cal]; – Guo Luchuan Feb 22 '13 at 10:03
  • @GuoLuchuan But the components were created *from* the calendar. – trojanfoe Feb 22 '13 at 10:04
  • Or use `NSCalendar`'s `-dateFromComponents:` directly instead of `NSDateComponent`'s `-date` method. I never liked that one, anyway. – Fabian Kreiser Feb 22 '13 at 10:07
  • OK answer restored with all its inperfection ;-) – trojanfoe Feb 22 '13 at 10:08