Как узнать, находится ли NSDate в указанном диапазоне? - PullRequest
6 голосов
/ 07 апреля 2011

Итак, мне трудно (не каламбур) выяснить, находится ли NSDate в определенном диапазоне.Подумайте об этом: запланированный визит с 17:00 до 18:00.Я хочу узнать, запланировано ли посещение в течение +/- 15 минут текущего времени.Таким образом, мой диапазон safe составляет от 16:45 до 18:15.Как я могу узнать, находится ли запланированный визит в пределах или за пределами диапазона?Вот код, который я получил до сих пор, который не работает вообще ...

- (BOOL)isInScheduledRange {
//    NSLog(@"Start: %f", [self.start timeIntervalSinceNow]);
//    NSLog(@"End: %f", [self.end timeIntervalSinceNow]);
//    
//    if (([self.start timeIntervalSinceNow] >= -900) && ([self.end timeIntervalSinceNow] <= 3600)) {
//        NSLog(@"In Range");
//        
//        return YES;
//    }
//    
    NSDate *now = [[NSDate alloc] init];

//    if ((([self.start timeIntervalSinceDate:now] >= -900) && ([self.start timeIntervalSinceDate:now] <= 900)) && (([self.end timeIntervalSinceDate:now] <= -900) && ([self.end timeIntervalSinceDate:now] >= 900))) {
//        NSLog(@"In Range");
//    }

    NSLog(@"%@; %@; %@", now, self.start, self.end);
//    NSLog(@"%@; %@", [self.start timeIntervalSinceDate:now], [self.end timeIntervalSinceDate:now]);

    if ((([self.start timeIntervalSinceDate:now] >= -900) && ([self.start timeIntervalSinceDate:now] <= 0)) && (([self.end timeIntervalSinceDate:now] >= 0) && ([self.end timeIntervalSinceDate:now] <= 900))) {
        NSLog(@"In Range");
    }

    return NO;

    [now release];
}

Буду признателен за некоторую помощь.У меня трудности с подсчетом времени.

С другой стороны, я ненавижу иметь дело со временем независимо от того, с какой платформой я работаю ...

Ответы [ 4 ]

6 голосов
/ 07 апреля 2011

Вы хотите проверить, меньше ли время начала менее 900 секунд после текущего времени, а время окончания меньше 900 секунд до текущего времени.timeIntervalSinceDate: возвращает положительное число, если объект, для которого он вызывается, равен после аргумента, вам необходимо проверить начало <= 900 и конец> = −900.Кроме того, вы можете упростить свой код, используя timeIntervalSinceNow вместо того, чтобы вручную получать текущую дату и передавать ее в timeIntervalSinceDate:.Наконец, если вы можете предположить (или ранее гарантировали), что начало предшествует концу, тогда вам не нужны два промежуточных теста, поскольку оба они должны быть истинными, чтобы оба других были верными.

if([self.start timeIntervalSinceNow] <= 900 && [self.end timeIntervalSinceNow] >= −900) {
    NSLog(@"In range")
}
3 голосов
/ 07 апреля 2011

Вот некоторый подробный (и глупый) код, который объясняет мой подход к этой проблеме

NSTimeInterval secondsBeforeStart = [self.start timeIntervalSinceNow];
if ( secondsBeforeStart > (15 * 60))
{
    // The result for '[self.start timeIntervalSinceNow]' is positive as long
    //  as 'self.start' remains in the future. We're not in range until there
    //  are 900 seconds to go or less.
    NSLog( @"Still time to chill.");

    // More than fifteen minutes to go so return NO.
    return NO;
}
else
{
    NSLog( @"OMG did I miss it!!!");
    NSTimeInterval secondsBeforeEnd = [self.end timeIntervalSinceNow];
    if ( secondsBeforeEnd < -( 15 * 60))
    {
        // The result for '[self.end timeIntervalSinceNow]' is negative when
        //  'self.end' is in the past. 
        // It's been more than 900 seconds since the end of the appointment
        //  so we've missed it.
        NSLog( @"Ahhhhh!!!");

        // More than 900 seconds past the end of the event so return NO.
        return NO;
    }
    else
    {
        // We are somewhere between 900 seconds before the start and
        //  900 seconds before the end so we are golden.
        NSLog( @"Whew, we made it.");
        return YES;
    }
}

То, как я бы его кодировал, было бы

BOOL inRange = NO;  // Assume we are not in the proper time range.

if ( [self.start timeIntervalSinceNow] <= ( 15 * 60))
{
    // 'Now' is at least 900 seconds before the start time but could be later.
    if ( [self.end timeIntervalSinceNow] >= -( 15 * 60))
    {
        // 'Now' is not yet 900 seconds past the end time.
        inRange = YES
    }
}

return inRange;

Примечание: у меня естьНа самом деле это не скомпилировано, но я уверен, что логика верна.

Наконец, вы заметили, что ваши последние две строки

    return NO;

    [now release];
}

привели бы к утечке памяти.(Отпустите, а затем вернитесь; ^))

2 голосов
/ 07 апреля 2011

Это проблема расстояния - вы хотите знать, находится ли текущее время в пределах 900 секунд от целевого времени. Вычислите проблемы расстояния, взяв абсолютное значение разности между двумя точками. Принимая абсолютное значение разницы, порядок двух образцов не имеет значения.

/** 
 * @brief Return YES if the current time is within 900 seconds of the meeting time (NSDate* time).
 */
-(BOOL)currentTimeIsWithin900SecondsOf:(NSDate*)time
{
    NSDate* now = [NSDate date];
    return fabs( [now timeIntervalSinceReferenceDate] - [time timeIntervalSinceReferenceDate] ) < 900;
}
0 голосов
/ 07 апреля 2011

Вам нужно создать три NSDates. Затем преобразуйте NSDates во временные интервалы с помощью intervalSinceReferenceDate и сравните их. Вы вручную настраиваете NSDates, используя NSDateComponents.

...