首页 > 解决方案 > Swift 5:如何从提供的字符串计算正确的日期?

问题描述

我不擅长 Swift 所以我想知道如何计算当前时间在两次之间。

我从后端得到以下响应。 {"workHours":"M-F 9:00 - 18:00"}

如何使用正则表达式和 DateFormatter 从响应中获取start(9:00) 时间、end(18:00) 时间"M-F 11:00 - 20:00"?(我不确定从这种字符串中获取 Date 对象是否正确,如果不是请推荐最好的方法和经验)

标签: swiftregexdatetimecalculation

解决方案


您可以使用以下正则表达式:

"^\\w-\\w\\s{1}(\\d{1,2}:\\d{2})\\s{1}-\\s{1}(\\d{1,2}:\\d{2})$"

分解

^ 断言行首的位置
AZ A(索引 65)和 Z(索引 90)之间范围内的单个字符(区分大小写)
- 匹配字符 - 字面上(区分大小写)
AZ A 之间范围内的单个字符(索引 65)和 Z(索引 90)(区分大小写)
\s 匹配任何空白字符(等于 [\r\n\t\f\v]){1} 量词 - 只匹配一次无意义的量词)
第一次捕获Group (\d{1,2}:\d{2})
\d{1,2} 匹配一个数字(等于 [0-9])
{1,2} 量词 - 匹配 1 到 2 次,如尽可能多次,根据需要返回(贪婪)
:匹配字符:字面上(区分大小写)
\d{2} 匹配一个数字(等于 [0-9])
\s 匹配任何空白字符(等于 [\r\n\t\f\v]) {1} 量词 - 只匹配一次(无意义
的量词) - 匹配字符 - 字面意思(区分大小写)
\s{1}匹配任何空白字符(等于 [\r\n\t\f\v ]) {1} 量词 — 只匹配一次(无意义的量词)
第二个捕获组 (\d{1,2}:\d{2} )
$ 在行尾断言位置


let response = "M-F 11:00 - 20:00"
let pattern = "^[A-Z]-[A-Z]\\s{1}(\\d{1,2}:\\d{2})\\s{1}-\\s{1}(\\d{1,2}:\\d{2})$"
let regex = try! NSRegularExpression(pattern: pattern)
if let match = regex.matches(in: response, range: .init(response.startIndex..., in: response)).first,
    match.numberOfRanges == 3 {
    match.numberOfRanges
    let start = match.range(at: 1)
    print(response[Range(start, in: response)!])
    let end = match.range(at: 2)
    print(response[Range(end, in: response)!])
}

这将打印

11:00
20:00

要获取开始时间和结束时间之间的时间差(这认为生成的字符串将与上述正则表达式匹配:

extension StringProtocol {
    var minutesFromTime: Int {
        let index = firstIndex(of: ":")!
        return Int(self[..<index])! * 60 + Int(self[index...].dropFirst())!
    }
}

let start = response[Range(match.range(at: 1), in: response)!]
let end = response[Range(match.range(at:2), in: response)!]
let minutes = end.minutesFromTime - start.minutesFromTime // 540
let hours = Double(minutes) / 60  // 9

推荐阅读