I have an app that I'm building in Swift that needs to determine if a store/restaurant is currently open. It queries a database that I have control of, so I can set the open hours however I'd like. Currently I have an openTime/closeTime column for each day of the week set as a timestamp. For example: MonOpen = 11:00, MonClose = 19:00.
How can I use swift to determine if the place of business is currently open? I'm imagining something like if currentTime > MonOpen & currentTime < MonClose {...
An example of this is the iOS Starbucks app. If you go to locations, each location is listed with an "Open until 22:00" or "Open until 23:00."
It's just a matter of playing with the timezone, whether you use the user system's timezone or let them choose another one in the app's settings:
let tz = NSTimeZone.defaultTimeZone()
let now = NSCalendar.currentCalendar().componentsInTimeZone(tz, fromDate: NSDate())
if now.weekDay == 2 && now.hour > MonOpen && now.hour < MonClose {
// The store is open
}
I would like to take another crack at this question since we now have Swift 5.1 and most businesses have more complex opening times than just in hours.
import Foundation
// There might be an enum in Swift
// that I did not bother to lookup
enum Days : Int {
case Sun = 1
case Mon = 2
case Tue = 3
case Wed = 4
case Thu = 5
case Fri = 6
case Sat = 7
}
func isOfficeOpenNow(weekSchedule: [Days: (Int, Int)]) -> Bool {
let tz = NSTimeZone.default
let now = NSCalendar.current.dateComponents(in: tz, from: Date())
guard let weekday = now.weekday,
let today = Days(rawValue: weekday),
let hour = now.hour,
let minute = now.minute else {
return false
}
guard let todayTuple = weekSchedule[today] else {
return false // no key, means closed
}
let opensAt = todayTuple.0
let closesAt = todayTuple.1
assert(opensAt < closesAt, "Your schedule is setup wrong.")
let rightNowInMinutes = hour * 60 + minute
return rightNowInMinutes > opensAt &&
rightNowInMinutes < closesAt
}
To use this just define a dictionary for each day.
Key is the dayofweek. Could have used a string "Mon","Tue",etc
but then you will need a mapping or DateFormatter
Value is a tuple (int, int) for (open, close) in minutes
Using minutes, as many stores have more complex open
closing times than just hours
let schedule = [
Days.Mon: (9*60+30, 22*60+30),
Days.Tue: (9*60+30, 23*60+05),
Days.Wed: (9*60+30, 22*60+30),
Days.Thu: (9*60+30, 22*60+30),
Days.Fri: (9*60+30, 22*60+30),
]
if isOfficeOpenNow(weekSchedule: schedule) {
print("Store open")
} else {
print("Store closed")
}
If a specific week is a holiday, just update the schedule for the week and all is good with the world.
If a day is closed, just remove the key from the schedule.