【发布时间】:2020-08-29 00:53:44
【问题描述】:
我正在尝试编写一个我有两次 time[hh:min] 数据(字符串类型)的代码。只需要比较,但挑战是我的代码在返回最终值之前经过了一些验证。所以断言有时会失败,说明预期值为 [17:04] 但实际值为 [17:05]。有什么方法可以使用阈值的概念,直到几分钟(比如 2 分钟)比较仍然有效?
【问题讨论】:
-
将其解析为
Date,然后进行比较?
我正在尝试编写一个我有两次 time[hh:min] 数据(字符串类型)的代码。只需要比较,但挑战是我的代码在返回最终值之前经过了一些验证。所以断言有时会失败,说明预期值为 [17:04] 但实际值为 [17:05]。有什么方法可以使用阈值的概念,直到几分钟(比如 2 分钟)比较仍然有效?
【问题讨论】:
Date,然后进行比较?
第一步是不要将事物存储为不是的事物。如果这些是时间,则应将它们存储为时间。字符串用于向用户表示;底层存储是为了现实。
现在让我们将时间存储为日期组件:
let t1 = DateComponents(hour:17, minute:4)
let t2 = DateComponents(hour:17, minute:5)
现在很容易找出它们之间的距离:
let cal = Calendar(identifier: .gregorian)
if let d1 = cal.date(from: t1),
let d2 = cal.date(from: t2) {
let diff = abs(d1.timeIntervalSince(d2))
// and now decide what to do
}
【讨论】:
您首先需要将您的字符串分离为一个数组,然后您可以进行比较。
/* That two arrays are A1 and A2 */
let minute1 = Int(A1[0])*60+Int(A1[1])
let minute2 = Int(A2[0])*60+Int(A2[1])
这可能会对您有所帮助。我认为@Sweeper 不明白这是一个时间,而不是一个日期。
【讨论】:
您可以将您的字符串转换为分钟,从另一个中减去一个并检查绝对值是否小于阈值:
extension String {
var time24hToMinutes: Int? {
guard count == 5, let hours = Int(prefix(2)), let minutes = Int(suffix(2)), Array(self)[2] == ":" else { return nil }
return hours * 60 + minutes
}
func time24hCompare(to other: String, threshold: Int = 2) -> Bool {
guard let lhs = time24hToMinutes, let rhs = other.time24hToMinutes else { return false }
return abs(lhs-rhs) < threshold
}
}
测试:
"17:02".time24hCompare(to: "17:04") // false
"17:03".time24hCompare(to: "17:04") // true
"17:04".time24hCompare(to: "17:04") // true
"17:05".time24hCompare(to: "17:04") // true
"17:06".time24hCompare(to: "17:04") // false
【讨论】: