检查当前时间是否在考虑午夜之后的时间范围之间 - 斯威夫特

时间:2018-04-02 12:49:04

标签: ios swift

我有休息时间的餐厅营业时间:

[
   {
      "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
}

我的工作是:

  1. 通过设置今日对象的时间
  2. 将字符串转换为日期对象
  3. 然后检查关闭时间是否在第二天(最差的部分)
  4. 然后检查关闭时间是否小于开放时间(例如:"openingAt":"07:30:00", "closingAt":"01:00:00"
  5. 然后检查当前时间是否在开始和结束时间之间
  6. 任何改变这种混乱的方法建议?

2 个答案:

答案 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数组中。