【问题标题】:how to check if time is within a specific range in swift如何快速检查时间是否在特定范围内
【发布时间】:2015-04-15 14:18:08
【问题描述】:

您好,我正在尝试检查当前时间是否在某个时间范围内,例如 8:00 - 16:30。下面的代码显示我可以将当​​前时间作为字符串获取,但我不确定如何使用该值来检查它是否在上面指定的时间范围内。任何帮助将不胜感激!

var todaysDate:NSDate = NSDate()
var dateFormatter:NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
var dateInFormat:String = dateFormatter.stringFromDate(todaysDate)
println(dateInFormat) // 23:54

【问题讨论】:

    标签: swift time


    【解决方案1】:

    有很多方法可以做到这一点。就个人而言,如果可以避免的话,我不喜欢使用字符串。我宁愿处理日期组件。

    下面是为 8:00 和 16:30 创建日期的代码,然后比较日期以查看当前日期/时间是否在该范围内。

    它比其他人的代码长,但我认为值得学习如何使用日历对日期进行计算:

    编辑#3:

    这个答案是很久以前的了。我将在下面留下旧答案,但这是当前的解决方案:

    @CodenameDuchess 的回答使用了系统函数,date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)

    使用该函数,代码可以简化为:

    import UIKit
    
    // The function `Calendar.date(bySettingHour:minute:second)` lets you 
    // create date objects for a given time in the same day of given date
    // For example, 8:00 today
    
    let calendar = Calendar.current
    let now = Date()
    let eight_today = calendar.date(
      bySettingHour: 8,
      minute: 0,
      second: 0,
      of: now)!
    
    let four_thirty_today = calendar.date(
      bySettingHour: 16,
      minute: 30,
      second: 0,
      of: now)!
    
    // In recent versions of Swift Date objectst are comparable, so you can 
    // do greater than, less than, or equal to comparisons on dates without
    // needing a date extension
    
    if now >= eight_today &&
      now <= four_thirty_today
    {
      print("The time is between 8:00 and 16:30")
    }
    

    为了历史的完整性,下面是旧的 (Swift 2) 答案:

    此代码使用 Calendar 对象获取当前日期的日/月/年,并添加所需的小时/分钟组件,然后为这些组件生成日期。

    import UIKit
    //-------------------------------------------------------------
    //NSDate extensions.
    extension NSDate
    {
      /**
      This adds a new method dateAt to NSDate.
    
      It returns a new date at the specified hours and minutes of the receiver
    
      :param: hours: The hours value
      :param: minutes: The new minutes
    
      :returns: a new NSDate with the same year/month/day as the receiver, but with the specified hours/minutes values
      */
      func dateAt(#hours: Int, minutes: Int) -> NSDate
      {
        let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    
        //get the month/day/year componentsfor today's date.
    
        println("Now = \(self)")
    
        let date_components = calendar.components(
          NSCalendarUnit.CalendarUnitYear |
            NSCalendarUnit.CalendarUnitMonth |
            NSCalendarUnit.CalendarUnitDay,
          fromDate: self)
    
        //Create an NSDate for 8:00 AM today.
        date_components.hour = hours
        date_components.minute = minutes
        date_components.second = 0
    
        let newDate = calendar.dateFromComponents(date_components)!
            return newDate
      }
    }
    //-------------------------------------------------------------
    //Tell the system that NSDates can be compared with ==, >, >=, <, and <= operators
    extension NSDate: Equatable {}
    extension NSDate: Comparable {}
    
    //-------------------------------------------------------------
    //Define the global operators for the 
    //Equatable and Comparable protocols for comparing NSDates
    
    public func ==(lhs: NSDate, rhs: NSDate) -> Bool
    {
      return lhs.timeIntervalSince1970 == rhs.timeIntervalSince1970
    }
    
    public func <(lhs: NSDate, rhs: NSDate) -> Bool
    {
      return lhs.timeIntervalSince1970 < rhs.timeIntervalSince1970
    }
    public func >(lhs: NSDate, rhs: NSDate) -> Bool
    {
      return lhs.timeIntervalSince1970 > rhs.timeIntervalSince1970
    }
    public func <=(lhs: NSDate, rhs: NSDate) -> Bool
    {
      return lhs.timeIntervalSince1970 <= rhs.timeIntervalSince1970
    }
    public func >=(lhs: NSDate, rhs: NSDate) -> Bool
    {
      return lhs.timeIntervalSince1970 >= rhs.timeIntervalSince1970
    }
    //-------------------------------------------------------------
    
    let now = NSDate()
    let eight_today = now.dateAt(hours: 8, minutes: 0)
    let four_thirty_today = now.dateAt(hours:16, minutes: 30)
    
    if now >= eight_today &&
      now <= four_thirty_today
    {
      println("The time is between 8:00 and 16:30")
    }
    

    编辑:

    这个答案中的代码已经为 Swift 3 改变了很多。

    使用原生的Date 对象而不是使用NSDate 更有意义,而Date 对象是EquatableComparable“开箱即用”。

    因此,我们可以摆脱 EquatableComparable 扩展以及 &lt;&gt;= 运算符的定义。

    然后我们需要对dateAt 函数中的语法进行大量调整,以遵循 Swift 3 语法。新的扩展在 Swift 3 中看起来像这样:

    Swift 3 版本:

    import Foundation
    
    extension Date
    {
    
      func dateAt(hours: Int, minutes: Int) -> Date
      {
        let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
    
        //get the month/day/year componentsfor today's date.
    
    
        var date_components = calendar.components(
          [NSCalendar.Unit.year,
           NSCalendar.Unit.month,
           NSCalendar.Unit.day],
          from: self)
    
        //Create an NSDate for the specified time today.
        date_components.hour = hours
        date_components.minute = minutes
        date_components.second = 0
    
        let newDate = calendar.date(from: date_components)!
        return newDate
      }
    }
    
    
    let now = Date()
    let eight_today = now.dateAt(hours: 8, minutes: 0)
    let four_thirty_today = now.dateAt(hours: 16, minutes: 30)
    
    if now >= eight_today &&
      now <= four_thirty_today
    {
      print("The time is between 8:00 and 16:30")
    }
    

    【讨论】:

    • 上面的代码似乎可以工作,但是当前时间是格林威治标准时间。有没有办法在手机上创建一个使用本地时区的 NSDate 对象,或者一个指定的对象,例如澳大利亚东部时间,即 UTC/GMT + 10。
    • NSDates 不使用任何时区。它们始终以 GMT/UTC 格式在内部存储。只有当您显示它们时,您才能在特定时区看到它们。在特定时区显示日期的最简单方法是使用日期格式化程序。 (虽然看起来println("\(someDate)") 语法显示在设备的默认语言环境中。
    • 是的,但是如果进行某种计算(例如比较),那么我的结果会不会不正确,因为我没有考虑偏移量?或者,我认为我可以将我的 8:00 和 16:30 转换为 GMT,这应该可以。
    • 没有。 NSDates 描述了地球上任何地方的某个时刻。他们在内部使用 UTC。如果 2 个 NSDate 相同,则它们描述的时间都是相同的时刻,而与时区无关。
    • 感谢 Duncan 的澄清,我测试了它,它就像你说的那样工作。干杯。
    【解决方案2】:

    在 Swift 3.0 中,您可以使用新的 Date 值类型并直接与 ==、>、

    let now = NSDate()
    let nowDateValue = now as Date
    let todayAtSevenAM = calendar.date(bySettingHour: 7, minute: 0, second: 0, of: nowDateValue, options: [])
    let todayAtTenPM = calendar.date(bySettingHour: 22, minute: 0, second: 0, of: nowDateValue, options: [])
    
    if nowDateValue >= todayAtSevenAM! &&
       nowDateValue <= todayAtTenPM!
    {
        // date is in range
    }
    

    确实很方便。

    【讨论】:

    • 折旧...?
    • 公爵夫人,很好的答案,使用date(bySettingHour:minute:second:of:)。这是一个似乎错过了的较新的Calendar 函数。它消除了对我的 Date 扩展的需要。
    • 其实看起来date(bySettingHour:minute:second:of:options:)是一个NSCalendar函数,等效的Swift 3 Calendar函数是date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)
    • 感谢它在 swift 3 中对我有用,我正在使用以下代码: let todayAtEightAM = calendar.date(bySettingHour: hourStart, minute: minStart, second: 00, of: nowDateValue) let todayAtSevenThirtyPM = calendar。 date(bySettingHour: hourEnd, minute: minEnd, second: 00, of: nowDateValue)
    【解决方案3】:

    以下解决方案从系统获取当前时间,然后检查它是否存在该范围。 在我的情况下,时间范围是上午 8:00 到下午 5:00 适用于 Swift 4.2 的解决方案

     func CheckTime()->Bool{
        var timeExist:Bool
        let calendar = Calendar.current
        let startTimeComponent = DateComponents(calendar: calendar, hour:8)
        let endTimeComponent   = DateComponents(calendar: calendar, hour: 17, minute: 00)
    
        let now = Date()
        let startOfToday = calendar.startOfDay(for: now)
        let startTime    = calendar.date(byAdding: startTimeComponent, to: startOfToday)!
        let endTime      = calendar.date(byAdding: endTimeComponent, to: startOfToday)!
    
        if startTime <= now && now <= endTime {
            print("between 8 AM and 5:30 PM")
            timeExist = true
        } else {
            print("not between 8 AM and 5:30 PM")
            timeExist = false
        }
        return timeExist
    }
    

    【讨论】:

      【解决方案4】:

      您可以从今天的日期获取年、月和日,将它们附加到这些日期时间字符串以构建新的Date 对象。然后comparetodaysDate 到这两个结果Date 对象:

      let todaysDate  = Date()
      let startString = "8:00"
      let endString   = "16:30"
      
      // convert strings to `Date` objects
      
      let formatter = DateFormatter()
      formatter.dateFormat = "HH:mm"
      let startTime = formatter.date(from: startString)
      let endTime = formatter.date(from: endString)
      
      // extract hour and minute from those `Date` objects
      
      let calendar = Calendar.current
      
      var startComponents = calendar.dateComponents([.hour, .minute], from: startTime!)
      var endComponents = calendar.dateComponents([.hour, .minute], from: endTime!)
      
      // extract day, month, and year from `todaysDate`
      
      let nowComponents = calendar.dateComponents([.month, .day, .year], from: todaysDate)
      
      // adjust the components to use the same date
      
      startComponents.year  = nowComponents.year
      startComponents.month = nowComponents.month
      startComponents.day   = nowComponents.day
      
      endComponents.year  = nowComponents.year
      endComponents.month = nowComponents.month
      endComponents.day   = nowComponents.day
      
      // combine hour/min from date strings with day/month/year of `todaysDate`
      
      guard
          let startDate = calendar.date(from: startComponents),
          let endDate = calendar.date(from: endComponents)
      else {
          print("unable to create dates")
          return
      }
      
      // now we can see if today's date is inbetween these two resulting `NSDate` objects
      
      let isInRange = todaysDate > startDate && todaysDate < endDate
      

      有关 Swift 2 的答案,请参阅 previous revision of this answer

      【讨论】:

        【解决方案5】:

        另外,如果我想查看一天中的时间是否在特定范围内,下面的解决方案看起来很短

        var greeting = String()
        let date     = Date()
        let calendar = Calendar.current
        let hour     = calendar.component(.hour, from: date)
        //let minutes  = calendar.component(.minute, from: date)
        let morning = 3; let afternoon=12; let evening=16; let night=22;
        
        print("Hour: \(hour)")
        if morning < hour, hour < afternoon {
            greeting = "Good Morning!"
        }else if afternoon < hour, hour < evening{
            greeting = "Good Afternoon!"
        }else if evening < hour, hour < night{
            greeting = "Good Evening!"
        }else{
            greeting = "Good Night"
        }
        print(greeting)
        

        我想你可以修改它,例如检查月份是否也在特定范围内,例如:

        sum = "Jan"
        win = "March"
        Spr = "May"
        Aut = "Sept"
        

        然后从那里继续...

        【讨论】:

        • 这个最好也最简单!
        【解决方案6】:

        这是我在当前项目之一中使用的一些代码。只需设置开始时间为 8:00,结束时间为 16:30,timeStamp 为当前时间。

        func isTimeStampCurrent(timeStamp:NSDate, startTime:NSDate, endTime:NSDate)->Bool{
            timeStamp.earlierDate(endTime) == timeStamp && timeStamp.laterDate(startTime) == timeStamp
        }
        

        【讨论】:

        • 感谢大家的反馈。我现在正在经历,看看哪一个最容易实现。
        【解决方案7】:

        您可以使NSDate 符合Comparable 协议,以便能够使用==!=&lt;=&gt;=&gt;&lt; 运算符。例如:

        extension NSDate : Comparable {}
        
        //  To conform to Comparable, NSDate must also conform to Equatable.
        //  Hence the == operator.
        public func == (lhs: NSDate, rhs: NSDate) -> Bool {
            return lhs.compare(rhs) == .OrderedSame
        }
        
        public func > (lhs: NSDate, rhs: NSDate) -> Bool {
            return lhs.compare(rhs) == .OrderedDescending
        }
        
        public func < (lhs: NSDate, rhs: NSDate) -> Bool {
            return lhs.compare(rhs) == .OrderedAscending
        }
        
        public func <= (lhs: NSDate, rhs: NSDate) -> Bool {
            return  lhs == rhs || lhs < rhs
        }
        
        public func >= (lhs: NSDate, rhs: NSDate) -> Bool {
            return lhs == rhs || lhs > rhs
        }
        

        要使用它来检查日期是否在您可以使用的两个日期内:

        let currentDate = NSDate()
        let olderDate   = NSDate(timeIntervalSinceNow: -100)
        let newerDate   = NSDate(timeIntervalSinceNow: 100)
        
        olderDate < currentDate && currentDate < newerDate // Returns true
        

        这里有几个示例说明如何将运算符与NSDate 一起使用:

        olderDate < newerDate  // True
        olderDate > newerDate  // False
        olderDate != newerDate // True
        olderDate == newerDate // False
        

        【讨论】:

        • 我的回答中也有这个问题,但是 Swift 3 使 Date 对象兼容且相等,因此不再需要此扩展。
        【解决方案8】:

        查看此链接

        要知道如何在swift中使用dateformator,请查看下面的链接

        https://nsscreencast.com/episodes/367-dates-and-times

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含essential parts of the answer 并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
        【解决方案9】:

        您可以使用NSDate 中的compare 方法:它将返回一个NSComparisonResultOrderedSameOrderedAscendingOrderedDescending),您可以检查您的开始日期和结束日期:

        let dateMaker = NSDateFormatter()
        dateMaker.dateFormat = "yyyy/MM/dd HH:mm:ss"
        let start = dateMaker.dateFromString("2015/04/15 08:00:00")!
        let end = dateMaker.dateFromString("2015/04/15 16:30:00")!
        
        func isBetweenMyTwoDates(date: NSDate) -> Bool {
            if start.compare(date) == .OrderedAscending && end.compare(date) == .OrderedDescending {
                return true
            }
            return false
        }
        
        println(isBetweenMyTwoDates(dateMaker.dateFromString("2015/04/15 12:42:00")!)) // prints true
        println(isBetweenMyTwoDates(dateMaker.dateFromString("2015/04/15 17:00:00")!)) // prints false
        

        【讨论】:

          【解决方案10】:
          extension Date { 
              /// time returns a double for which the integer represents the hours from 1 to 24 and the decimal value represents the minutes.  
              var time: Double {
                  Double(Calendar.current.component(.hour, from: self)) + Double(Calendar.current.component(.minute, from: self)) / 100
              }
          }
          
          // usage 
          print(9.30...16.30 ~= Date().time ? "If you're on the East Coast, It is during market hours" : "its after hours")
          

          【讨论】:

            【解决方案11】:

            你可以这样比较日期。

            extension NSDate {
            
            func isGreaterThanDate(dateToCompare: NSDate) -> Bool {
                //Declare Variables
                var isGreater = false
            
                //Compare Values
                if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending {
                    isGreater = true
                }
            
                //Return Result
                return isGreater
            }
            
            func isLessThanDate(dateToCompare: NSDate) -> Bool {
                //Declare Variables
                var isLess = false
            
                //Compare Values
                if self.compare(dateToCompare) == NSComparisonResult.OrderedAscending {
                    isLess = true
                }
            
                //Return Result
                return isLess
            }
            
            func equalToDate(dateToCompare: NSDate) -> Bool {
                //Declare Variables
                var isEqualTo = false
            
                //Compare Values
                if self.compare(dateToCompare) == NSComparisonResult.OrderedSame {
                    isEqualTo = true
                }
            
                //Return Result
                return isEqualTo
            }
            
            func addDays(daysToAdd: Int) -> NSDate {
                let secondsInDays: NSTimeInterval = Double(daysToAdd) * 60 * 60 * 24
                let dateWithDaysAdded: NSDate = self.dateByAddingTimeInterval(secondsInDays)
            
                //Return Result
                return dateWithDaysAdded
            }
            
            func addHours(hoursToAdd: Int) -> NSDate {
                let secondsInHours: NSTimeInterval = Double(hoursToAdd) * 60 * 60
                let dateWithHoursAdded: NSDate = self.dateByAddingTimeInterval(secondsInHours)
            
                //Return Result
                return dateWithHoursAdded
             }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-10-23
              • 2011-12-21
              • 2020-07-28
              • 2016-05-03
              • 1970-01-01
              • 1970-01-01
              • 2018-04-07
              • 1970-01-01
              相关资源
              最近更新 更多