我有休息时间的餐厅营业时间:
[
{
"weekday":0,
"openingAt":"07:30:00",
"closingAt":"00:45:00"
},
{
"weekday":1,
"openingAt":"07:30:00",
"closingAt":"23:00:00"
},
{
"weekday":2,
"openingAt":"07:30:00",
"closingAt":"23:00:00"
},
{
"weekday":3,
"openingAt":"07:30:00",
"closingAt":"23:00:00"
},
{
"weekday":4,
"openingAt":"07:30:00",
"closingAt":"23:00:00"
},
{
"weekday":5,
"openingAt":"07:30:00",
"closingAt":"23:00:00"
},
{
"weekday":6,
"openingAt":"07:30:00",
"closingAt":"01:00:00"
}
]
我为支票创建了计算属性:
var isClosed: Bool {
let todayIndex = (Calendar.current.component(.weekday, from: Date()) - 1) % 7
let yesterdayIndex = (Calendar.current.component(.weekday, from: Date()) - 2) % 7
let todayDate = Date()
if let wh = workingHour, wh.count > 7 {
let todayWh = wh[todayIndex]
if let openingStr = todayWh.openingAt, openingStr != "",
let openingDate = Date().setTimeHHmmss(formattedString: openingStr),
let closingStr = todayWh.closingAt, closingStr != "",
let closingDate = Date().setTimeHHmmss(formattedString: closingStr)
{
let yesterdayWh = wh[yesterdayIndex]
var fromYesterdayExtraHours = 0
if let yesterdayClosingStr = yesterdayWh.closingAt,
let yClosingDate = Date().setTimeHHmmss(formattedString: yesterdayClosingStr) {
if yClosingDate.hour > 0 {
fromYesterdayExtraHours = yClosingDate.hour
}
}
if closingDate < openingDate {
if todayDate.hour < fromYesterdayExtraHours {
return false // opened
} else {
return true // closed
}
} else if todayDate >= openingDate && todayDate <= closingDate {
return false // opened
} else {
return true // closed
}
}
}
return false // opened
}
我的工作是:
"openingAt":"07:30:00", "closingAt":"01:00:00"
任何改变这种混乱的方法建议?
答案 0 :(得分:2)
我的建议是将JSON解析为具有Decodable
的结构,并且为了方便起见,将开始和结束时间解释为DateComponents
。
我认为weekday == 0
是星期日
let jsonString = """
[
{"weekday":0, "openingAt":"07:30:00", "closingAt":"00:45:00"},
{"weekday":1, "openingAt":"07:30:00", "closingAt":"23:00:00"},
{"weekday":2, "openingAt":"07:30:00", "closingAt":"23:00:00"},
{"weekday":3, "openingAt":"07:30:00", "closingAt":"23:00:00"},
{"weekday":4, "openingAt":"07:30:00", "closingAt":"23:00:00"},
{"weekday":5, "openingAt":"07:30:00", "closingAt":"23:00:00"},
{"weekday":6, "openingAt":"07:30:00", "closingAt":"01:00:00"}
]
"""
struct Schedule : Decodable {
let weekday : Int
let openingAt : DateComponents
let closingAt : DateComponents
private enum CodingKeys: String, CodingKey { case weekday, openingAt, closingAt }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
weekday = (try container.decode(Int.self, forKey: .weekday)) + 1
let open = try container.decode(String.self, forKey: .openingAt)
let openComponents = open.components(separatedBy:":")
openingAt = DateComponents(hour: Int(openComponents[0]), minute: Int(openComponents[1]), second: Int(openComponents[2]))
let close = try container.decode(String.self, forKey: .closingAt)
let closeComponents = close.components(separatedBy:":")
closingAt = DateComponents(hour: Int(closeComponents[0]), minute: Int(closeComponents[1]), second: Int(closeComponents[2]))
}
}
现在首先声明,今天开始和当前日历
let now = Date()
let calendar = Calendar.current
let midnight = calendar.startOfDay(for: now)
然后解码JSON,按工作日过滤今天的时间表,通过添加日期组件创建开始和结束时间并比较日期。 endDate
的计算方法是在开始日期之后查找给定日期组件的下一次出现。如果截止日期是明天,这就解决了这个问题。
do {
let data = Data(jsonString.utf8)
let schedule = try JSONDecoder().decode([Schedule].self, from: data)
let todaySchedule = schedule.first{ $0.weekday == calendar.component(.weekday, from: now) }
let startDate = calendar.date(byAdding: todaySchedule!.openingAt, to: midnight)!
let endDate = calendar.nextDate(after: startDate, matching: todaySchedule!.closingAt, matchingPolicy: .nextTime)!
let isOpen = now >= startDate && now < endDate
} catch { print(error) }
有一个限制:如果当前时间在0:00 to closing time
范围内(例如星期日和星期一),则代码不起作用。这对你来说是一个挑战
答案 1 :(得分:2)
这是我的解决方案,通过使用具有分钟和小时的结构作为Int&#39>采取一种不同的方法
struct Time: Comparable {
var hour = 0
var minute = 0
init(hour: Int, minute: Int) {
self.hour = hour
self.minute = minute
}
init(_ date: Date) {
let calendar = Calendar.current
hour = calendar.component(.hour, from: date)
minute = calendar.component(.minute, from: date)
}
static func == (lhs: Time, rhs: Time) -> Bool {
return lhs.hour == rhs.hour && lhs.minute == rhs.minute
}
static func < (lhs: Time, rhs: Time) -> Bool {
return (lhs.hour < rhs.hour) || (lhs.hour == rhs.hour && lhs.minute < rhs.minute)
}
static func create(time: String) -> Time? {
let parts = time.split(separator: ":")
if let hour = Int(parts[0]), let minute = Int(parts[1]) {
return Time(hour: hour, minute: minute)
}
return nil
}
static func isOpen(open: Time, close: Time) -> Bool {
let isClosingAfterMidnight = close.hour < open.hour ? true : false
let currentTime = Time(Date())
if isClosingAfterMidnight {
return currentTime > close && currentTime < open ? false : true
}
return currentTime >= open && currentTime < close
}
}
它可以像
一样使用if let open = Time.create(time: todayWh.openingAt), let close = Time.create(time: todayWh.closingAt) {
return Time.isOpen(open: open, close: close))
} else {
//error handling
}
它也应该在午夜之后工作:)当然Time结构可以直接用在wh数组中。