在Swift中计算两个日期之间的时差

Mis*_*cha 10 date ios dateinterval swift

我已经看到了许多方法来根据特定的日期组件来计算两个日期之间的差异,例如,以天,小时,月等为单位(请参见Stackoverflow上的此答案):

Calendar.current.dateComponents([.hour], from: fromDate, to: toDate).hour
Calendar.current.dateComponents([.day], from: fromDate, to: toDate).day
Calendar.current.dateComponents([.month], from: fromDate, to: toDate).month
Run Code Online (Sandbox Code Playgroud)

我还没有看到如何使用实际Date对象进行计算。就像是

func computeNewDate(from fromDate: Date, to toDate: Date) -> Date    
     let delta = toDate - fromDate
     let today = Date()
     if delta < 0 {
         return today
     } else {
         return today + delta
     }
}
Run Code Online (Sandbox Code Playgroud)

我已经看到了DateIntervaliOS 10中引入的类型,但是根据文档

[it]不支持反向间隔,即持续时间小于0且结束日期在时间上早于开始日期的间隔。

这样就很难计算日期,尤其是当您不知道哪个是较早的日期时。

是否有任何简洁的方法可以Date直接计算s 之间的时间差(并将它们Date再次添加到实例中)而无需使用它们进行计算timeIntervalSinceReferenceDate

小智 55

您可以使用 :

let delta = fromDate.distance(to: toDate)
Run Code Online (Sandbox Code Playgroud)

  • 这是一个超级有用的功能。只是,它仅适用于 iOS 13+ (3认同)

Mic*_*sen 26

您可以使用自定义运算符进行扩展,并返回元组

extension Date {

    static func -(recent: Date, previous: Date) -> (month: Int?, day: Int?, hour: Int?, minute: Int?, second: Int?) {
        let day = Calendar.current.dateComponents([.day], from: previous, to: recent).day
        let month = Calendar.current.dateComponents([.month], from: previous, to: recent).month
        let hour = Calendar.current.dateComponents([.hour], from: previous, to: recent).hour
        let minute = Calendar.current.dateComponents([.minute], from: previous, to: recent).minute
        let second = Calendar.current.dateComponents([.second], from: previous, to: recent).second

        return (month: month, day: day, hour: hour, minute: minute, second: second)
    }

}
Run Code Online (Sandbox Code Playgroud)

使用:

let interval = Date() - updatedDate
print(interval.day)
print(interval.month)
print(interval.hour)
Run Code Online (Sandbox Code Playgroud)

  • 这对我帮助很大。**在 swift 5 中正常工作**。多谢兄弟 (2认同)

Mis*_*cha 11

我最终为创建了一个自定义运算符Date

extension Date {

    static func - (lhs: Date, rhs: Date) -> TimeInterval {
        return lhs.timeIntervalSinceReferenceDate - rhs.timeIntervalSinceReferenceDate
    }

}
Run Code Online (Sandbox Code Playgroud)

使用此运算符,我现在可以在更抽象的级别上计算两个日期之间的差,而无需关心timeIntervalSinceReferenceDate或确切地知道参考日期是什么,并且也不会损失精度,例如:

let delta = toDate - fromDate
Run Code Online (Sandbox Code Playgroud)

显然,我并没有做太多更改,但是对我来说,它更具可读性和结果:Swift +已经为a Date和a 实现了运算符TimeInterval

/// Returns a `Date` with a specified amount of time added to it.
public static func + (lhs: Date, rhs: TimeInterval) -> Date
Run Code Online (Sandbox Code Playgroud)

所以它已经在支持

Date + TimeInterval = Date
Run Code Online (Sandbox Code Playgroud)

因此,它也应该支持

Date - Date = TimeInterval
Run Code Online (Sandbox Code Playgroud)

我认为,这就是我通过简单实现 -操作符。现在,我可以完全按照问题中的说明编写示例函数:

func computeNewDate(from fromDate: Date, to toDate: Date) -> Date    
     let delta = toDate - fromDate // `Date` - `Date` = `TimeInterval`
     let today = Date()
     if delta < 0 {
         return today
     } else {
         return today + delta // `Date` + `TimeInterval` = `Date`
     }
}
Run Code Online (Sandbox Code Playgroud)

很可能这是我目前尚不了解的一些缺点,我很想听听您对此的想法。


小智 6

我找到了一个内置解决方案来计算两个日期之间的差异。

let delta = toDate.timeIntervalSince(fromDate)

  • [这已经由 @cakraww 提出了建议](/sf/answers/3832617981/)。 (3认同)

cak*_*aww 5

简单地说toDate.timeIntervalSince(fromDate)

要重新实现您的功能而不添加任何扩展名:

func computeNewDate(from fromDate: Date, to toDate: Date) -> Date  {  
     let delta = toDate.timeIntervalSince(fromDate) 
     let today = Date()
     if delta < 0 {
         return today
     } else {
         return today.addingTimeInterval(delta) 
     }
}
Run Code Online (Sandbox Code Playgroud)