как проверить, находится ли время в определенном диапазоне в swift

Привет я пытаюсь проверить, находится ли текущее время в диапазоне времени, скажем, 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

9 ответов


есть много способов сделать это. Лично мне не нравится работать со струнами, если я могу этого избежать. Я бы предпочел иметь дело с компонентами даты.

ниже приведен код игровой площадки, который использует объект календаря для получения дня / месяца/года текущей даты и добавляет нужные компоненты часа / минуты, а затем генерирует дату для этих компонентов.

он создает даты для 8: 00 и 16: 30, а затем сравнивает даты, чтобы увидеть, если текущая дата/время попадает в это диапазон.

это больше, чем кода других людей, но я думаю, что стоит научиться делать вычисления с датами в календаре:

редактировать #3:

этот ответ давным-давно. Я оставлю старый ответ ниже, но вот текущее решение:

@CodenameDuchess' ответ использует системную функцию,date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)

используя эту функцию, код можно упростить до этого:

import UIKit

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)!

if now >= eight_today &&
  now <= four_thirty_today
{
  print("The time is between 8:00 and 16:30")
}

старый (Swift 2) ответ для исторической полноты:

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")
}

EDIT:

код в этом ответе сильно изменился для Swift 3.

вместо NSDate, это имеет больше смысла для нас родной


в Swift 3.0 вы можете использовать новый тип значения даты и сравнивать непосредственно с ==,>,

    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

    }

очень удобно.


Swift 3

Это функция, которая возвращает строку, путем сравнения, если текущее время находится в пределах указанного времени. Запустите его на игровой площадке и адаптируйте к своим потребностям.

func updateGreeting() -> String {

var greeting = String()

//date formatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "h:mm a"

// Get current time and format it to compare
var currentTime = Date()
let currentTimeStr = dateFormatter.string(from: currentTime)
currentTime = dateFormatter.date(from: currentTimeStr)!

//Times array
let startTimes = ["5:00 AM", //Morning
    "11:00 AM", //Aftenoon
    "5:00 PM", //Evening
    "9:00 PM" //Nigth
]

let morning = 0
let afternoon = 1
let evening = 2
let night = 3

var dateTimes = [Date]()

//create an array with the desired times
for i in 0..<startTimes.count{
    let dateTime = dateFormatter.date(from: startTimes[i])
    print(dateTime!)
    dateTimes.append(dateTime!)
}

if currentTime >= dateTimes[morning] && currentTime < dateTimes[afternoon]   {
    greeting = "Good Morning!"
}
if currentTime >= dateTimes[afternoon] && currentTime < dateTimes[evening]   {
    greeting = "Good Afternoon!"
}
if currentTime >= dateTimes[evening] && currentTime <= dateTimes[night]   {
    greeting = "Good Evening"
}
if currentTime >= dateTimes[night] && currentTime < dateTimes[morning]   {
    greeting = "Good Night"
}

return greeting

}


вы могли бы сделать NSDate соответствуют Comparable протокол, чтобы иметь возможность использовать ==, !=, <=, >=, > и < операторы. Например:

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

вы можете получить год, месяц и день от сегодняшней даты, добавьте их к этим строкам времени даты, чтобы построить новый NSDate объекты. Тогда compare на todaysDate к тем двум результирующим NSDate объекты:

let todaysDate  = NSDate()
let startString = "8:00"
let endString   = "16:30"

// convert strings to `NSDate` objects

let formatter = NSDateFormatter()
formatter.dateFormat = "HH:mm"
let startTime = formatter.dateFromString(startString)
let endTime = formatter.dateFromString(endString)

// extract hour and minute from those `NSDate` objects

let calendar = NSCalendar.currentCalendar()

let startComponents = calendar.components([.Hour, .Minute], fromDate: startTime!)
let endComponents = calendar.components([.Hour, .Minute], fromDate: endTime!)

// extract day, month, and year from `todaysDate`

let nowComponents = calendar.components([.Month, .Day, .Year], fromDate: 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`

let startDate = calendar.dateFromComponents(startComponents)
let endDate = calendar.dateFromComponents(endComponents)

// now we can see if today's date is inbetween these two resulting `NSDate` objects

let isInRange = todaysDate.compare(startDate!) != .OrderedAscending && todaysDate.compare(endDate!) != .OrderedDescending

вот код, который я использую в одном из моих текущих проектов. Просто установите время начала как 8: 00, Время окончания как 16: 30 и отметку времени как текущее время.

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

можно использовать compare метод NSDate: он вернет NSComparisonResult (OrderedSame, OrderedAscending или OrderedDescending), что вы можете проверить против даты начала и окончания:

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

вы можете сравнить дату, как это.

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

кроме того, Решение ниже выглядит коротким, если я хочу посмотреть, если время находится в определенном диапазоне в течение дня

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)

Я думаю, вы можете изменить его, чтобы проверить, например, если месяцы находятся в определенных диапазонах, e.g:

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

и продолжать оттуда...