使用Swift 3,根据您的需要,您可以选择以下两种方式之一来解决您的问题。
1. 向用户显示两个日期之间的差异
你可以使用DateComponentsFormatter为你的应用程序界面创建字符串。DateComponentsFormatter有一个maximumUnitCount属性,声明如下:
var maximumUnitCount: Int { get set }
使用此属性可限制结果字符串中显示的单位数量。例如,将此属性设置为2,而不是“1h 10m, 30s”,生成的字符串将是“1h 10m”。当空间受限或希望将值舍入到最近的大单位时,请使用此属性。
通过将maximumUnitCount的值设置为1,可以保证仅以一个DateComponentsFormatter的单位(年、月、日、小时或分钟)显示差异。
下面的Playground代码显示了如何显示两个日期之间的差异:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
注意,DateComponentsFormatter对结果进行四舍五入。因此,4小时和30分钟的差异将显示为5小时。
如果你需要重复这个操作,你可以重构你的代码:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. 在不设置格式的情况下获取两个日期之间的差异
如果不需要将两个日期之间的差异格式化显示给用户,则可以使用Calendar。日历有一个方法dateComponents(_:from:to:),它有以下声明:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
返回两个日期的差值。
下面使用dateComponents(_:from:to:)的Playground代码展示了如何通过只返回一种日历类型的差异来检索两个日期之间的差异。组件(年、月、日、小时或分钟)。
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
如果你需要重复这个操作,你可以重构你的代码:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}