首页 文章

如何检查两个其他NSDate之间是否发生NSDate

提问于
浏览
88

我试图用NSDate判断当前日期是否在日期范围内 .

例如,您可以使用NSDate获取当前日期/时间:

NSDate rightNow = [NSDate date];

然后,我想使用该日期来检查它是否在 9AM - 5PM 的范围内 .

10 回答

  • 4

    如果您想知道当前日期是否在两个给定时间点之间(2009年7月1日上午9点至下午5点),请使用NSCalendar和NSDateComponents构建所需时间的NSDate实例,并将它们与当前日期进行比较 .

    如果你想知道当前的日期是否每天都在这两个小时之间,那么你可能会走另一条路 . 使用和NSCalendar以及NSDate创建NSDateComponents对象并比较小时组件 .

  • 0

    这可以使用日期的时间间隔轻松完成,如下所示:

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

    我想出了一个解决方案 . 如果您有更好的解决方案,请随意离开,我会将其标记为正确 .

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

    对于第一部分,使用@kperryua中的答案来构造要与之比较的NSDate对象 . 根据你对自己问题的回答,听起来你已经弄明白了 .

    为了实际比较日期,我完全赞同@Tim 's comment on your answer. It'更简洁但实际上完全等同于你的代码,我将解释原因 .

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

    虽然看起来return语句必须评估&&运算符的两个操作数,但事实并非如此 . 关键是“short-circuit evaluation”,它用各种编程语言实现,当然用C语言实现 . 基本上,运算符 &&& "short circuit"如果第一个参数是0(或NO,nil等),而 ||| 如果第一个参数是 not ,则执行相同操作 . 如果 datebeginDate 之前,则测试返回 NO ,甚至不需要与 endDate 进行比较 . 基本上,它与您的代码完全相同,但在一行中的单个语句中,而不是5(或7,具有空格) .

    这是作为建设性的输入,因为当程序员理解他们的特定编程语言评估逻辑表达式的方式时,他们可以更有效地构建它们而不需要太多关于效率 . 然而,由于并非所有运营商都发生短路,因此有类似的测试,效率较低 . (实际上,大多数都不能短路,例如数值比较运算符 . )如果有疑问,明确分解逻辑总是安全的,但是当你让语言/编译器处理小事时,代码可以更加可读为了你 .

  • 0

    Swift中的Brock Woolf版本:

    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
        }
    }
    
  • 8

    继续使用Quinn和Brock的解决方案,非常好的继承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 :)

  • 160

    如果您可以定位iOS 10.0 / macOS 10.12,则使用 DateInterval 类 .

    首先,创建一个包含开始和结束日期的日期间隔:

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

    然后,使用 DateIntervalcontains 方法检查日期是否在间隔中:

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

    对于这个问题,有更好,更快速的解决方案 .

    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及以上版本中使用它 .

  • 5

    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
        }
    }
    
  • 2

    使用Swift 4.2和iOS 12,您可以使用以下两种解决方案之一来检查两个其他日期之间是否出现日期 .


    #1 . 使用DateInterval的contains(_ :)方法

    DateInterval 有一个名为contains(_:)的方法 . contains(_:) 有以下声明:

    func contains(_ date: Date) -> Bool
    

    指示此间隔是否包含给定日期 .

    以下Playground代码显示如何使用 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的contains(_ :)方法

    ClosedRange 有一个名为contains(_:)的方法 . contains(_:) 有以下声明:

    func contains(_ element: Bound) -> Bool
    

    返回一个布尔值,指示给定元素是否包含在范围内 .

    以下Playground代码显示如何使用 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
    

相关问题