Cómo comprobar si se produce un NSDate entre otros dos NSDates

Estoy tratando de averiguar si la fecha actual cae dentro de un rango de fechas usando NSDate.

Por ejemplo, puede obtener la fecha / hora actual usando NSDate:

NSDate rightNow = [NSDate date]; 

Entonces me gustaría usar esa fecha para verificar si está en el rango de 9AM a 5PM .

Encontré una solución. Si tiene una mejor solución, siéntase libre de dejarla y la marcaré como correcta.

 + (BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate { if ([date compare:beginDate] == NSOrderedAscending) return NO; if ([date compare:endDate] == NSOrderedDescending) return NO; return YES; } 

Para la primera parte, use la respuesta de @kperryua para construir los objetos NSDate con los que desea comparar. Desde su respuesta a su propia pregunta, parece que lo tiene claro.

Para comparar las fechas, estoy totalmente de acuerdo con el comentario de @Tim sobre tu respuesta. Es más conciso pero en realidad es exactamente equivalente a tu código, y explicaré por qué.

 + (BOOL) date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate { return (([date compare:beginDate] != NSOrderedAscending) && ([date compare:endDate] != NSOrderedDescending)); } 

Aunque puede parecer que la statement de devolución debe evaluar ambos operandos del operador &&, este no es realmente el caso. La clave es la ” evaluación de cortocircuito “, que se implementa en una amplia variedad de lenguajes de progtwigción, y ciertamente en C. Básicamente, los operadores & y && “cortocircuito” si el primer argumento es 0 (o NO, nulo, etc. .), mientras | y || haga lo mismo si el primer argumento no es 0. Si la date viene antes de beginDate , la prueba devuelve NO sin necesidad de comparar con endDate . Básicamente, hace lo mismo que su código, pero en una sola statement en una línea, no en 5 (o 7, con espacios en blanco).

Esto tiene la intención de ser un aporte constructivo, ya que cuando los progtwigdores entienden la forma en que su lenguaje de progtwigción particular evalúa las expresiones lógicas, pueden construirlas de manera más efectiva sin tanta eficiencia. Sin embargo, hay pruebas similares que serían menos eficientes, ya que no todos los operadores tienen un cortocircuito. (De hecho, la mayoría no puede cortocircuitarse, como los operadores de comparación numérica). En caso de duda, siempre es seguro ser explícito al separar su lógica, pero el código puede ser mucho más legible cuando permite que el lenguaje / comstackdor maneje las pequeñas cosas para ti.

La versión de Brock Woolf en Swift:

 extension NSDate { func isBetweenDates(beginDate: NSDate, endDate: NSDate) -> Bool { if self.compare(beginDate) == .OrderedAscending { return false } if self.compare(endDate) == .OrderedDescending { return false } return true } } 

Si desea saber si la fecha actual se encuentra entre dos puntos determinados en el tiempo (de 9 a. M. A 5 p. M. El 1 de julio de 2009), use NSCalendar y NSDateComponents para comstackr instancias de NSDate para los tiempos deseados y compárelos con la fecha actual.

Si desea saber si la fecha actual cae entre estas dos horas todos los días, entonces probablemente podría ir por el otro camino. Cree un objeto NSDateComponents con y NSCalendar y su NSDate y compare los componentes de la hora.

Esto se puede lograr fácilmente usando los intervalos de tiempo de las fechas, de esta manera:

 const NSTimeInterval i = [date timeIntervalSinceReferenceDate]; return ([startDate timeIntervalSinceReferenceDate] <= i && [endDate timeIntervalSinceReferenceDate] >= i); 

Continuando con las soluciones de Quinn y Brock, es muy agradable subclasificar la implementación de NSDate, por lo que se puede usar en todas partes de esta manera:

 -(BOOL) isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate { return (([self compare:beginDate] != NSOrderedAscending) && ([self compare:endDate] != NSOrderedDescending)); } 

Y en cualquier parte de tu código puedes usarlo como:

 [myNSDate isBetweenDate:thisNSDate andDate:thatNSDate]; 

(myNSDate, thisNSDate y thatNSDate son por supuesto NSDates 🙂

Hay una solución mejor y más rápida para este problema.

 extention Date { func isBetween(from startDate: Date,to endDate: Date) -> Bool { let result = (min(startDate, endDate) ... max(startDate, endDate)).contains(self) return result } } 

Entonces puedes llamarlo así.

 todayDate.isBetween(from: startDate, to: endDate) 

Incluso puede pasar la fecha al azar ya que esta extensión verifica cuál es mínima y cuál no.

puedes usarlo en Swift 3 y arriba.

Si puede apuntar a iOS 10.0 + / macOS 10.12+, entonces use la clase DateInterval .

Primero, crea un intervalo de fecha con una fecha de inicio y finalización:

 let start: Date = Date() let middle: Date = Date() let end: Date = Date() let dateInterval: DateInterval = DateInterval(start: start, end: end) 

Luego, verifique si la fecha está en el intervalo usando el método contains de DateInterval :

 let dateIsInInterval: Bool = dateInterval.contains(middle) // true 

Una mejor versión en Swift:

 @objc public class DateRange: NSObject { let startDate: Date let endDate: Date init(startDate: Date, endDate: Date) { self.startDate = startDate self.endDate = endDate } @objc(containsDate:) func contains(_ date: Date) -> Bool { let startDateOrder = date.compare(startDate) let endDateOrder = date.compare(endDate) let validStartDate = startDateOrder == .orderedAscending || startDateOrder == .orderedSame let validEndDate = endDateOrder == .orderedDescending || endDateOrder == .orderedSame return validStartDate && validEndDate } }