objective-cnsdatensdateformatternsorderedset

Compare local NSDate time to PST time operating hours


My app has a chat component where users talk directly to customer service representatives and I want to make sure to notify the user if they are requesting help during office hours.

The office hours are in pst from 9 am to 7 pm.

Here is my current code to display a notification to the user if the office is closed, but it is not working properly.

- (void)checkOfficeHours {

//set opening hours date
NSDateComponents *openingTime = [[NSDateComponents alloc] init];
openingTime.hour = 9;
openingTime.minute = 0;

//set closing time hours
NSDateComponents *closingTime = [[NSDateComponents alloc] init];
closingTime.hour = 19;
closingTime.minute = 0;

//get the pst time from local time
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat=@"hh:mm";
NSDate *currentDate = [NSDate date];
NSTimeZone *pstTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"PST"];
dateFormatter.timeZone = pstTimeZone;
NSString *pstTimeString = [dateFormatter stringFromDate:currentDate];

//convert pst date string back to date
NSDate *now = [dateFormatter dateFromString:pstTimeString];

//create the current date component
NSDateComponents *currentTime = [[NSCalendar currentCalendar] components:NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:now];

//sort the array by times
NSMutableArray *times = [@[openingTime, closingTime, currentTime] mutableCopy];
[times sortUsingComparator:^NSComparisonResult(NSDateComponents *t1, NSDateComponents *t2) {
    if (t1.hour > t2.hour) {
        return NSOrderedDescending;
    }

    if (t1.hour < t2.hour) {
        return NSOrderedAscending;
    }
    // hour is the same
    if (t1.minute > t2.minute) {
        return NSOrderedDescending;
    }

    if (t1.minute < t2.minute) {
        return NSOrderedAscending;
    }
    // hour and minute are the same
    if (t1.second > t2.second) {
        return NSOrderedDescending;
    }

    if (t1.second < t2.second) {
        return NSOrderedAscending;
    }
    return NSOrderedSame;

}];

//if the current time is in between (index == 1) then its during office hours
if ([times indexOfObject:currentTime] == 1) {
    NSLog(@"We are Open!");
    self.officeHoursView.hidden = YES;
} else {
    NSLog(@"Sorry, we are closed!");
    self.officeHoursView.hidden = NO;
}

}


Solution

  • If all you care about is whether it's currently between 9AM and 7PM PST, you can do it a lot more easily than that. Just get an NSDateComponents for the current time, in PST, and look at the hour property of the result.

    NSTimeZone *pst = [NSTimeZone timeZoneWithName:@"PST"];
    NSDateComponents *pstComponentsForNow = [[NSCalendar currentCalendar] componentsInTimeZone:pst fromDate:[NSDate date]];
    
    if ((pstComponentsForNow.hour >= 9) && (pstComponentsForNow.hour <= 19)) {
        NSLog(@"Open");
    } else {
        NSLog(@"Closed");
    }
    

    If you also care about the day of week or other details, look at other properties of NSDateComponents.