2011-04-07 11 views
6

Entonces, estoy teniendo un momento difícil (sin juego de palabras) para encontrar si un NSDate está dentro de un rango específico. Considere esto: una visita programada entre las 5:00 p.m. y las 6:00 p.m. Quiero encontrar si la visita programada está dentro de +/- 15 minutos de la hora actual. Por lo tanto, mi rango seguro es de 4:45 PM a 6:15 PM. ¿Cómo puedo averiguar si la visita programada está dentro o fuera del rango? Aquí está el código que tengo hasta ahora, que no funciona en absoluto ...¿Cómo encontrar si un NSDate está dentro de un rango específico?

- (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]; 
} 

Agradecería un poco de ayuda. Estoy teniendo dificultades con este cálculo de tiempo.

En una nota aparte, no me gusta tratar con el tiempo sin importar la plataforma que estoy trabajando ...

Respuesta

5

desea comprobar si la hora de inicio es de menos de 900 segundos después la hora actual y la hora de finalización es de menos de 900 segundos antes la hora actual. timeIntervalSinceDate: devuelve un número positivo si el objeto al que se llama es después de el argumento, debe verificar el inicio < = 900 y finalizar> = -900. Además, puede simplificar su código utilizando timeIntervalSinceNow en lugar de obtener manualmente la fecha actual y pasándola a timeIntervalSinceDate:. Finalmente, si puedes asumir (o aseguraste previamente) que el inicio es antes del final, entonces no necesitas las dos pruebas intermedias, ya que ambas tendrán que ser verdaderas para que las otras dos sean verdaderas.

if([self.start timeIntervalSinceNow] <= 900 && [self.end timeIntervalSinceNow] >= −900) { 
    NSLog(@"In range") 
} 
+0

Esta es una mejor respuesta que la mía. – Moshe

+0

Esto funcionó, y parece que mi primer intento comentado fue el más cercano. ¡Gracias por la ayuda! – Gup3rSuR4c

0

Es necesario crear tres NSDates. Luego convierta NSDates en intervalos de tiempo usando intervalSinceReferenceDate y compárelos. Configura NSDates manualmente utilizando NSDateComponents.

3

He aquí algunos prolijo (y tonto) de código que explica mi acercamiento a este problema

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; 
    } 
} 

La manera de que hubiera codificado que habría sido

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; 

Nota: No he En realidad compilé esto, pero estoy bastante seguro de que la lógica es correcta.

Por último, se dio cuenta de que sus dos últimas líneas

return NO; 

    [now release]; 
} 

habrían creado una pérdida de memoria. (Suelta y luego regresa; ^))

+0

Fue una elección difícil entre usted y @ughoavgfhw ya que ambos dijeron lo mismo esencialmente, pero al final el código de @ ughoavgfhw era prácticamente idéntico al que escribí, así que fui con él. ** SIN EMBARGO **, le agradezco la publicación * lol * y el consejo sobre la fuga. – Gup3rSuR4c

2

Este es un problema de distancia: quieres saber si la hora actual está dentro de 900 segundos del tiempo objetivo. Calcule los problemas de distancia tomando el valor absoluto de la diferencia entre los dos puntos. Tomando el valor absoluto de la diferencia, el orden de las dos muestras no importa.

/** 
* @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; 
} 
Cuestiones relacionadas