Swift实现:判断当前时间是否处于跨午夜的营业时间范围内
判断餐厅当前是否营业(Swift实现,支持跨午夜)
Got it,这个需求我之前帮不少开发者处理过,跨午夜的场景确实是最容易踩坑的点,咱们一步步把它搞定。
第一步:先把JSON数据映射成Swift模型
首先得把REST返回的营业时间数据转成Swift能直接用的结构体,用Codable来解析最省心:
struct BusinessHour: Codable { let weekday: Int // 这里注意:你的API定义0=周日、1=周一…6=周六,后面要对应Calendar的规则调整 let openingAt: String // 格式为"HH:mm:ss" let closingAt: String // 格式为"HH:mm:ss" }
第二步:核心判断逻辑(重点处理跨午夜)
接下来写核心的判断函数,关键是区分两种场景:正常时段(关门时间晚于开门时间)和跨午夜时段(关门时间早于开门时间,比如到次日凌晨00:45):
import Foundation extension BusinessHour { // 检查当前时间是否在本时段内 func isCurrentTimeInRange() -> Bool { let calendar = Calendar.current let now = Date() // Calendar里的weekday规则是1=周日、2=周一…7=周六,和API的0-6对应需要转换 let currentCalendarWeekday = calendar.component(.weekday, from: now) let mappedWeekday = weekday + 1 // 把API的0→1(周日)、1→2(周一)…以此类推 // 先判断是不是今天的营业时间,不是直接返回false guard mappedWeekday == currentCalendarWeekday else { return false } // 把字符串时间转成可比较的时分秒组件 let timeFormatter = DateFormatter() timeFormatter.dateFormat = "HH:mm:ss" timeFormatter.timeZone = calendar.timeZone // 用当前时区,避免时间偏移 guard let openingDate = timeFormatter.date(from: openingAt), let closingDate = timeFormatter.date(from: closingAt) else { // 时间格式解析失败,返回false return false } let openingComponents = calendar.dateComponents([.hour, .minute, .second], from: openingDate) let closingComponents = calendar.dateComponents([.hour, .minute, .second], from: closingDate) let currentComponents = calendar.dateComponents([.hour, .minute, .second], from: now) // 分两种情况处理 if closingDate > openingDate { // 正常时段:比如07:30到23:00,只要当前时间在两者之间 return currentComponents >= openingComponents && currentComponents <= closingComponents } else { // 跨午夜时段:比如07:30到00:45,当前时间≥07:30(当天) 或者 ≤00:45(次日凌晨) return currentComponents >= openingComponents || currentComponents <= closingComponents } } } // 给数组加个扩展,批量检查所有营业时间 extension Array where Element == BusinessHour { func isRestaurantOpenNow() -> Bool { return contains { $0.isCurrentTimeInRange() } } }
第三步:实际使用示例
假设你已经从接口拿到了营业时间数组,直接调用就行:
// 用你提供的示例数据测试 let sampleBusinessHours: [BusinessHour] = [ BusinessHour(weekday: 0, openingAt: "07:30:00", closingAt: "00:45:00"), BusinessHour(weekday: 1, openingAt: "07:30:00", closingAt: "23:00:00"), BusinessHour(weekday: 2, openingAt: "07:30:00", closingAt: "23:00:00"), BusinessHour(weekday: 3, openingAt: "07:30:00", closingAt: "23:00:00"), BusinessHour(weekday: 4, openingAt: "07:30:00", closingAt: "23:00:00"), BusinessHour(weekday: 5, openingAt: "07:30:00", closingAt: "23:00:00"), BusinessHour(weekday: 6, openingAt: "07:30:00", closingAt: "00:45:00") ] // 判断当前是否营业 let isOpen = sampleBusinessHours.isRestaurantOpenNow() print("餐厅当前是否营业:\(isOpen ? "是" : "否")")
几个要注意的细节
- 时区问题:如果餐厅在固定时区营业,记得把
timeFormatter.timeZone改成餐厅所在时区(比如TimeZone(identifier: "Asia/Shanghai")),避免用户跨时区时判断错误。 - Weekday映射:不同API的weekday定义可能不一样(比如有的0=周一),一定要根据实际接口文档调整
mappedWeekday的计算逻辑。 - 时间格式兼容:如果接口返回的时间格式有变化(比如不带秒),记得同步修改
dateFormat。
内容的提问来源于stack exchange,提问作者MBH
相关产品推荐
相关产品推荐

