How to determine if a business is open given the h

2020-07-27 17:07发布

问题:

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."

回答1:

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
}


回答2:

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.



标签: ios swift nsdate