Pergunta

Eu estou tentando descobrir se ou não a data atual cai dentro de um intervalo de datas usando NSDate.

Por exemplo, você pode obter a data / hora atual usando NSDate:

NSDate rightNow = [NSDate date];

Em seguida, gostaria de usar essa data para verificar se ele está na faixa de 9:00 -. 05:00

Foi útil?

Solução

Eu vim com uma solução. Se você tiver uma solução melhor, fique à vontade para deixá-lo e eu vou marcá-lo como correto.

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

Outras dicas

Para a primeira parte, use a resposta de @kperryua para construir o NSDate objetos que você deseja comparar com. Da sua resposta à sua própria pergunta, parece que você tem que descobri.

Para realmente comparar as datas, eu concordo totalmente com @ Tim comentário que está em sua resposta. É mais concisa mas, na verdade exatamente equivalente ao seu código, e vou explicar porquê.

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

Embora possa parecer que a instrução de retorno deve avaliar ambos os operandos do operador &&, isso não é realmente o caso. A chave é " curto-circuito avaliação", que é implementado em uma ampla variedade de programação línguas, e certamente em C. Basicamente, os operadores & e && "curto-circuito" se o primeiro argumento é 0 (ou NÃO, nil, etc.), enquanto < strong> | e || fazer o mesmo se o primeiro argumento é não 0. Se date vem antes beginDate, o teste retorna NO, mesmo sem a necessidade de comparar com endDate. Basicamente, ele faz a mesma coisa que o seu código, mas em uma única instrução em uma linha, não 5 (ou 7, com espaços em branco).

Este é concebido como contribuição construtiva, desde quando programadores compreender a forma como a sua linguagem de programação específica avalia expressões lógicas, eles podem construí-los de forma mais eficaz, sem tanto sobre a eficiência. No entanto, existem testes semelhantes que seria ser menos eficiente, uma vez que nem todos os operadores de curto-circuito. (Na verdade, a maioria não pode de curto-circuito, tais como operadores de comparação numérica.) Em caso de dúvida, é sempre mais seguro para ser explícito em quebrando sua lógica, mas o código pode ser muito mais legível quando você deixar o linguagem / compilador lidar com as pequenas coisas para você.

Versão Brock Woolf em 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
    }
}

Se você quer saber se a data atual cai entre dois pontos dados no tempo (nove horas - cinco horas em 7/1/09), use NSCalendar e NSDateComponents para construir instâncias NSDate para os tempos desejados e compará-los com a data atual .

Se você quer saber se a data atual cai entre estas duas horas todas dia, então você provavelmente poderia ir por outro caminho. Criar um NSDateComponents objeto com e NSCalendar e seu NSDate e comparar os componentes hora.

Isso pode ser feito facilmente usando intervalos de tempo das datas, assim:

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

Continuando com soluções Brock's Quinn e, é muito agradável para subclasse implementação NSDate, para que ele possa ser usado em todos os lugares como este:

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

E, em qualquer parte do seu código você pode usá-lo como:

[myNSDate isBetweenDate:thisNSDate andDate:thatNSDate];

(myNSDate, thisNSDate e thatNSDate são naturalmente NSDates :)

Se você pode direcionar iOS 10,0 + / MacOS 10.12+, em seguida, usar a classe DateInterval.

Primeiro, crie um intervalo de datas com uma data de início e término:

let start: Date = Date()
let middle: Date = Date()
let end: Date = Date()

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

Em seguida, verifique se a data é no intervalo usando o método contains de DateInterval:

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

Não é melhor e solução mais swifty 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
    }
}

Depois, você pode chamá-lo assim.

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

Mesmo que você pode passar data aleatória a essa extensão verifica qual é mínimo e que um em não.

Você pode usá-lo em Swift 3 e acima.

Com Swift 5, você pode usar uma das duas soluções a seguir, a fim de verificar se uma data ocorre entre duas outras datas.


# 1. Usando o método DateInterval de contains(_:)

DateInterval tem um método chamado contains(_:) . contains(_:) tem a seguinte declaração:

func contains(_ date: Date) -> Bool

Indica se este intervalo contém a data dada.

Os seguintes mostra o código Parque como usar contains(_:), a fim de verificar se uma data ocorre entre duas outras datas:

import Foundation

let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let myDate = calendar.date(from: DateComponents(year: 2012, month: 8, day: 15))!

let dateInterval = DateInterval(start: startDate, end: endDate)
let result = dateInterval.contains(myDate)
print(result) // prints: true

# 2. Usando o método ClosedRange de contains(_:)

ClosedRange tem um método chamado contains(_:) . contains(_:) tem a seguinte declaração:

func contains(_ element: Bound) -> Bool

Retorna um valor booleano que indica se o elemento de dado está contido dentro do intervalo.

Os seguintes mostra o código Parque como usar contains(_:), a fim de verificar se uma data ocorre entre duas outras datas:

import Foundation

let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let myDate = calendar.date(from: DateComponents(year: 2012, month: 8, day: 15))!

let range = startDate ... endDate
let result = range.contains(myDate)
//let result = range ~= myDate // also works
print(result) // prints: true

Uma versão melhor em 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
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top