Iain Grant
Iain Grant

Reputation: 95

Check if time is before or after two saved text string times

I have two times stored in an NSDictionary. "Start time" is 22:30 and "End time" is 4:00 am.

I need to figure out if the current time is before start time, before end time, or after the end time and before the next time start time rolls around.

I'm sure I'm making this far more complicated than it needs to be, but in trying to cover off all the possibilities I've completely confused myself.

NSDictionary *noaudio = [[NSUserDefaults standardUserDefaults] objectForKey:@"NoSound"];
NSDateFormatter *tformat = [[NSDateFormatter alloc] init];
[tformat setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];  
[tformat setDateFormat:@"HH:mm"];

date1 = [tformat dateFromString:[noaudio objectForKey:@"start"]];
date2 = [tformat dateFromString:[noaudio objectForKey:@"end"]];
date3 = [NSDate date];

Would I have to check both date 1 and 2 against 3?

Thanks for any guidance on this one.

Upvotes: 3

Views: 1287

Answers (2)

lnafziger
lnafziger

Reputation: 25740

Well, with only two times and no dates, you can only find out whether or not the current time is between the start and end times. This is because, in your example above (start time 22:30 and end time 04:00) what would you return for 13:00? It is both "after the end time" (04:00) and "before start time" (22:30) today.

That being said, here is one way to check to see if the current time is between the times specified in two dates. You could do this by keeping everything as a NSDate (using calendar operations) but it makes it even more complicated because you have to create new NSDate objects using today's date with the specified times. It isn't too hard, but there is no reason to do it unless you are using them elsewhere.

// Take a date and return an integer based on the time.
// For instance, if passed a date that contains the time 22:30, return 2230
- (int)timeAsIntegerFromDate:(NSDate *)date {
    NSCalendar *currentCal      = [NSCalendar currentCalendar];
    NSDateComponents *nowComps  = [currentCal components:NSHourCalendarUnit|NSMinuteCalendarUnit fromDate:date];
    return nowComps.hour * 100 + nowComps.minute;
}

// Check to see if the current time is between the two arbitrary times, ignoring the date portion:
- (BOOL)currentTimeIsBetweenTimeFromDate1:(NSDate *)date1 andTimeFromDate2:(NSDate *)date2 {
    int time1     = [self timeAsIntegerFromDate:date1];
    int time2     = [self timeAsIntegerFromDate:date2];
    int nowTime   = [self timeAsIntegerFromDate:[NSDate date]];

    // If the times are the same, we can never be between them
    if (time1 == time2) {
        return NO;
    }

    // Two cases:  
    // 1.  Time 1 is smaller than time 2 which means that they are both on the same day
    // 2.  the reverse (time 1 is bigger than time 2) which means that time 2 is after midnight
    if (time1 < time2) { 
        // Case 1
        if (nowTime > time1) {
            if (nowTime < time2) {
                return YES;
            }
        }
        return NO;
    } else { 
        // Case 2
        if (nowTime > time1 || nowTime < time2) {
            return YES;
        }
        return NO;
    }
}

Upvotes: 1

samson
samson

Reputation: 1152

Why not just store the NSDate in the NSDictionary? Then, you can use timeIntervalSinceReferenceDate or timeIntervalSince1970 to get an NSTimeInterval (which is really just a double) and do a simple comparison.

If you just have times, it's impossible to tell if they're on the same date or not, so I don't see a general solution which will work when the start time is before midnight and the end time is after...

In any case, even if you can't just store the NSDate (Is this the case? Are the times coming from some external source?), your life will be much simpler if you convert to a double and just use < and >.

Upvotes: 0

Related Questions