how to check if time is within a specific range in swift
swift, time
Solution
There are lots of ways to do this. Personally, I don't like working with strings if I can avoid it. I'd rather deal with date components.
Below is code that creates dates for 8:00 and 16:30, and then compares the dates to see if the current date/time falls in that range.
It's longer than other people's code, but I think it's worth learning how to do calculations with dates using a Calendar:
EDIT #3:
This answer is from a long time ago. I'll leave the old answer below, but here is the current solution:
@CodenameDuchess' answer uses a system function, `date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)`
Using that function, the code can be simplified to this:
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")
}
The old (Swift 2) answer follows, for historical completeness:
This code uses a Calendar object to get the day/month/year of the current date, and adds the desired hour/minute components, and then generates a date for those components.
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:
The code in this answer has changed a LOT for Swift 3.
Instead of using `NSDate`, it makes more sense to us the native `Date` object, and `Date` objects are `Equatable` and `Comparable` "out of the box".
Thus we can get rid of the `Equatable` and `Comparable` extensions and the definitions for the `<`, `>` and `=` operators.
Then we need to do a fair amount of tweaking of the syntax in the `dateAt` function to follow Swift 3 syntax. The new extension looks like this in Swift 3:
Swift 3 version:
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")
}
Problem
Hi I am trying to check if the current time is within a time range, say 8:00 - 16:30. My code below shows that I can obtain the current time as a string, but I am unsure how I can use this value to check if it is inside the time range specified above. Any help would be greatly appreciated! ``` var todaysDate:NSDate = NSDate() var dateFormatter:NSDateFormatter = NSDateFormatter() dateFormatter.dateFormat = "HH:mm" var dateInFormat:String = dateFormatter.stringFromDate(todaysDate) println(dateInFormat) // 23:54 ```