提问人:iKK 提问时间:2/4/2023 最后编辑:iKK 更新时间:2/4/2023 访问量:54
检查两个日期之间是否在 iOS16.3 下不再有效
Check if between two dates is no longer working under iOS16.3
问:
使用 iOS16.3、XCode14.2、Swift5.7.2、
为什么以下方法不再有效?
我通过设置和以及...date = Date()
maximumDate = Date()
根据这个解决方案,它应该有效 - 但它没有
public class THManager : ObservableObject {
@Published public var minimumDate: Date = Date()
@Published public var maximumDate: Date = Date()
public func isBetweenMinAndMaxDates(date: Date) -> Bool {
print(min(minimumDate, maximumDate))
print(max(minimumDate, maximumDate))
print(min(minimumDate, maximumDate)...max(minimumDate, maximumDate))
print(date)
print((min(minimumDate, maximumDate)...max(minimumDate, maximumDate)).contains(date))
return (min(minimumDate, maximumDate)...max(minimumDate, maximumDate)).contains(date)
}
}
2022-02-08 19:45:51 +0000
2023-02-03 19:45:51 +0000
2022-02-08 19:45:51 +0000...2023-02-03 19:45:51 +0000
2023-02-03 19:45:51 +0000
false
它应该回来!为什么它返回 false ???true
顺便说一句,如果和date = Date()
maximumDate = Date().addingTimeInterval(1)
很奇怪,不是吗?
答:
1赞
Duncan C
2/4/2023
#1
没有必要如此复杂。日期对象符合 和 协议,因此测试介于 2 个其他日期之间的日期是一行:Comparable
Equatable
extension Date {
func between(start: Date, end: Date) -> Bool {
return self > start && self < end
}
}
你可以这样使用它:
let date = Date()
if date.betweeen(start: someDate, end: someOtherDate) {
// the date is between the start and the end
} else {
// The date is not between the start and end dates
}
仅当相关日期不等于开始日期或结束日期时,上述内容才会返回 true。您可以通过在比较中使用 和 而不是 和 轻松更改它以匹配与开始日期和结束日期匹配的日期。>=
<=
>
<
正如评论中所讨论的,Date 对象具有亚毫秒级精度。两个看起来相同的日期可能相差几分之一秒,验证比较的最佳方法是将日期转换为十进制秒并记录秒值。(请参阅属性。Date
timeIntervalSinceReferenceDate
编辑:
使用上述示例查看此示例代码:
extension Date {
func between(start: Date, end: Date) -> Bool {
return self > start && self < end
}
var asStringWithDecimal: String {
return DateFormatter.localizedString(from: self, dateStyle: .medium, timeStyle: .medium) + " ( \(self.timeIntervalSinceReferenceDate) seconds)"
}
}
let now = Date()
for _ in (1...5) {
let random = Double.random(in: -1.5...1.5)
let test = now.advanced(by: random)
let start = now.advanced(by: -1)
let end = now.advanced(by: 1)
let isBetween = test.between(start: start, end: end)
let isOrNot = isBetween ? "is" : "is not"
let output = "\(test.asStringWithDecimal) \n \(isOrNot) between \n \(start.asStringWithDecimal) and \n \(end.asStringWithDecimal)"
print(output)
}
这将在当前日期的 1.5 秒±生成 5 个随机日期,然后测试每个日期以查看它是否在当前日期的 1 秒内。它将结果记录为日期字符串和双精度,因此您可以看到秒数匹配时发生的情况(但秒的分数可能不匹配)。
评论
0赞
iKK
2/4/2023
非常感谢邓肯 - 非常好的解决方案。真正欺骗我的是,我的maximumDate=Date()比date=Date()早了几分之一秒 - 这使得两者不同!日志没有考虑到这一点。
0赞
Duncan C
2/4/2023
请参阅对我的答案的编辑。我添加了一些测试代码,将日期记录为日期字符串和双精度,以便您可以查看非常接近开始或结束日期的日期发生了什么。
0赞
Duncan C
2/4/2023
如果您想知道您的日期是否介于其他两个日期与第二个日期之间,可以截断日期的 timeIntervalSinceReferenceDate 值并进行比较。如果要与其他精度(如分钟、小时或天)进行比较,可以使用 日历 函数 .这将使您判断您的日期是否在相同的秒、分钟、小时、日、周或您想要的任何时间。Date
compare(_:to:toGranularity:)
评论
TimeInterval
Date