Как проверить, возникает ли NSDate между двумя другими NSDate

Я пытаюсь выяснить, попадает ли текущая дата в диапазон дат, используя NSDate.

Например, вы можете получить текущую дату / время, используя NSDate:

NSDate rightNow = [NSDate date];

Затем я хотел бы использовать эту дату, чтобы проверить, находится ли она в диапазоне9AM - 5PM.

 Marc Charbonneau02 июл. 2009 г., 17:14
Вы можете взглянуть на ответы наэтот вопро для получения дополнительной информации о том, как создавать объекты NSDate для определенного периода времени, например, с 17:00 до 21:0

Ответы на вопрос(10)

Решение Вопроса

не стесняйтесь оставить его, и я отмечу его как правильное.

+ (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;
}
 Jeff Kelley02 июл. 2009 г., 20:40
Это выглядит хорошо, но вы можете переименовать его примерно так: + (BOOL) date: (NSDate *) date isBetweenDate: (NSDate *) beginDate andDate: (NSDate *) endDate, чтобы избежать путаницы.
 Dave Batton28 дек. 2010 г., 19:22
Еще лучше, я бы сделал это методом экземпляра (дополнение к NSDate), а не методом класса. Я бы пошел с этим: -isBetweenDate: andDate:
 Matteo Alessani11 июл. 2011 г., 10:24
Превосходно! Я сделал категорию из этого:- (BOOL)isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate;
 Gabriele Petronella28 дек. 2012 г., 16:40
хорошее решение, вы даже можете сделать его менее подробным из-за короткого замыкания (и базовое приложение Де Моргана.return !([date compare:startDate] == NSOrderedAscending || [date compare:endDate] == NSOrderedDescending);
 Tim04 июл. 2009 г., 07:45
Код гольф! Компилятор должен замкнуть сравнение, сделав эффективность примерно равной вашей: return (([date Compare: beginDate]! = NSOrderedDescending) && ([Date Compare: endDate]! = NSOrderedAscending));

Лучшая версия в 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
    }
}

попадает ли текущая дата между двумя указанными точками времени (с 9:00 до 17:00 01.07.09), используйте NSCalendar и NSDateComponents, чтобы создать экземпляры NSDate для желаемого времени и сравнить их с текущей датой.

Если вы хотите знать, попадает ли текущая дата между этими двумя часами Каждый день, тогда ты мог бы пойти другим путем. Создайте объект NSDateComponents с помощью и NSCalendar и NSDate и сравните часовые компоненты.

очень приятно создавать подклассы реализации NSDate, поэтому его можно использовать везде, например так:

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

И в любой части вашего кода вы можете использовать его как:

[myNSDate isBetweenDate:thisNSDate andDate:thatNSDate];

(myNSDate, thisNSDate и thatNSDate - это, конечно, NSDates:)

 Supertecnoboff16 мая 2018 г., 01:24
Это здорово, спасибо!

DateInterval учебный класс

Во-первых, создайте интервал дат с начальной и конечной датами:

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

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

Затем проверьте, находится ли дата в интервале, используяcontains методDateInterval:

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

@ kperryua для создания объектов NSDate, с которыми вы хотите сравнить. Из твоего ответа на свой вопрос, похоже, ты понял это.

Для сравнения дат я полностью согласен с@Ти комментарий к вашему ответу. Это более кратко, но на самом деле точно соответствует вашему коду, и я объясню почему.

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

Хотя может показаться, что оператор return должен оценивать оба операнда оператора &&, на самом деле это не так. Ключ " оценка короткого замыкания ", который реализован в самых разных языках программирования и, конечно, в C. В основном, операторы& а также&& "короткое замыкание", если первый аргумент равен 0 (или НЕТ, ноль и т. д.), а| а также|| сделать то же самое, если первый аргументн 0. Еслиdate предшествуетbeginDate, тест возвращаетсяNO даже не нужно сравнивать сendDate. По сути, он делает то же самое, что и ваш код, но одним оператором в одной строке, а не 5 (или 7, с пробелами).

Это задумано как конструктивный ввод, поскольку, когда программисты понимают, как их конкретный язык программирования оценивает логические выражения, они могут конструировать их более эффективно, не обращая особого внимания на эффективность. Однако есть похожие тесты, которыебыло б быть менее эффективным, так как не все операторы замкнуты. (Действительно, большинствоне могу короткое замыкание, такое как операторы числового сравнения.) В случае сомнений всегда можно быть явным при разделении логики, но код может быть намного более читабельным, если вы разрешите языку / компилятору обрабатывать мелочи для вас.

 Brock Woolf12 июл. 2009 г., 07:27
Understandable. Я понятия не имел, что Objective-C будет закорачивать оценки. Я верю твоему слову, что это так. Спасибо за разъяснение этого для меня. Полагаю, я отмечу вас как правильную, поскольку ваш ответ более лаконичен, чем мой ... и я кое-что узнал
 Quinn Taylor12 июл. 2009 г., 16:40
Не нужно верить мне на слово - я отстаиваю принцип «доверяй, но проверяй» (спасибо, Рональд Рейган!) Только для того, чтобы удовлетворить мое любопытство и узнать границы того, когда что-то работает, а что нет. Вы можете проверить это, выполнив && двух методов, которые регистрируют то, что они возвращают при вызове; вы заметите, что если первый вернет 0, второй никогда не будет вызван.
 Brock Woolf13 июл. 2009 г., 05:55
Конечно, я напишу что-нибудь для проверки.

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

Есть лучшее и более быстрое решение этой проблемы.

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

Тогда ты можешь называть это так.

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

Даже если вы можете передать случайную дату, это расширение проверяет, какое из них минимальное, а какое нет.

Вы можете использовать его в Swift 3 и выше.

чтобы проверить, встречается ли дата между двумя другими датами.

# 1. С помощьюDateInterval scontains(_:) метод

DateInterval имеет метод с именемcontains(_:). contains(_:) имеет следующую декларацию:

func contains(_ date: Date) -> Bool

Указывает, содержит ли этот интервал заданную дату.

Следующий код игровой площадки показывает, как использоватьcontains(_:) чтобы проверить, встречается ли дата между двумя другими датами:

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. С помощьюClosedRange scontains(_:) метод

ClosedRange имеет метод с именемcontains(_:). contains(_:) имеет следующую декларацию:

func contains(_ element: Bound) -> Bool

Возвращает логическое значение, указывающее, содержится ли данный элемент в диапазоне.

Следующий код игровой площадки показывает, как использоватьcontains(_:) чтобы проверить, встречается ли дата между двумя другими датами:

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

Версия Брука Вульфа в 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
    }
}

Ваш ответ на вопрос