objective c - Cómo comprobar si se produce un NSDate entre otros dos NSDates
objective-c cocoa (9)
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 :)
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;
}
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);
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.
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
}
}
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 declaración 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 programació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 declaración 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 programadores entienden la forma en que su lenguaje de programació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 / compilador maneje las pequeñas cosas para ti.
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 compilar 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.
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
}
}