how to check if time is within a specific range in swift
The Following soltion get current time from the system and then check it exist that range or not . In my case time range is 8:00 am to 5:00 pm The Solution Valid for 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
}
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")
}
In Swift 3.0 you can use the new Date value type and compare directly with ==,>,< etc
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
}
Very handy indeed.