我有一个应用程序,提供每30秒到期的数据(确切地说,在h/m/s 11:30:00,11:30:30,11:31:00等).
我可以得到当前时间,但我不确定如何计算从现在到最近的30秒之间的时间.
我发现的任何东西都在Objective-C中,我一直无法转换它.
这是我试过的:
func nearestThirtySeconds() -> Date? {
var components = NSCalendar.current.dateComponents([.second], from: self)
let second = components.second ?? 30
components.second = second >= 30 ? 60 - second : -second
return Calendar.current.date(byAdding: components, to: self)
}
Run Code Online (Sandbox Code Playgroud)
但这会返回最近的分钟(我想,它总是会返回一分钟)
有任何想法吗?
您可以将秒数舍入到最接近的30的倍数,然后将舍入值和原始值之间的差值添加到日期:
extension Date {
func nearestThirtySeconds() -> Date {
let cal = Calendar.current
let seconds = cal.component(.second, from: self)
// Compute nearest multiple of 30:
let roundedSeconds = lrint(Double(seconds) / 30) * 30
return cal.date(byAdding: .second, value: roundedSeconds - seconds, to: self)!
}
}
Run Code Online (Sandbox Code Playgroud)
这应该足以显示四舍五入的时间,但不准确:A Date还包括小数秒,因此例如"11:30:10.123"将变为"11:30:00.123"而不是"11:30:00.000" ".这是解决该问题的另一种方法:
extension Date {
func nearestThirtySeconds() -> Date {
let cal = Calendar.current
let startOfMinute = cal.dateInterval(of: .minute, for: self)!.start
var seconds = self.timeIntervalSince(startOfMinute)
seconds = (seconds / 30).rounded() * 30
return startOfMinute.addingTimeInterval(seconds)
}
}
Run Code Online (Sandbox Code Playgroud)
现在seconds是自当前分钟开始以来的时间间隔(包括小数秒).该间隔四舍五入到最接近的30的倍数并添加到分钟的开头.
我使用了Martin R的答案来编写一个更通用的版本来循环任何时间段.
答案已过时,仅适用于时间,请查看要点以获取最新版本.
https://gist.github.com/casperzandbergenyaacomm/83c6a585073fd7da2e1fbb97c9bcd38a
extension Date {
func rounded(on amount: Int, _ component: Calendar.Component) -> Date {
let cal = Calendar.current
let value = cal.component(component, from: self)
// Compute nearest multiple of amount:
let roundedValue = lrint(Double(value) / Double(amount)) * amount
let newDate = cal.date(byAdding: component, value: roundedValue - value, to: self)!
return newDate.floorAllComponents(before: component)
}
func floorAllComponents(before component: Calendar.Component) -> Date {
// All components to round ordered by length
let components = [Calendar.Component.year, .month, .day, .hour, .minute, .second, .nanosecond]
guard let index = components.index(of: component) else {
fatalError("Wrong component")
}
let cal = Calendar.current
var date = self
components.suffix(from: index + 1).forEach { roundComponent in
let value = cal.component(roundComponent, from: date) * -1
date = cal.date(byAdding: roundComponent, value: value, to: date)!
}
return date
}
}
Run Code Online (Sandbox Code Playgroud)
要舍入到x分钟,您还需要对秒数进行处理,因此这也包含我写的底层方法.
如何使用:
let date: Date = Date() // 10:16:34
let roundedDate0 = date.rounded(on: 30, .second) // 10:16:30
let roundedDate1 = date.rounded(on: 15, .minute) // 10:15:00
let roundedDate2 = date.rounded(on: 1, .hour) // 10:00:00
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2278 次 |
| 最近记录: |