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

时间:2018-06-20 14:01:20

标签: ios swift date dateinterval

我已经看到了许多方法,如何根据特定的日期成分来计算两个日期之间的差异,例如以天,小时,月等为单位(请参见this answer on 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

我还没有看到如何使用实际的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
     }
}

我已经看到DateInterval类型,它是iOS 10中引入的,但根据文档显示

  

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

这使得计算日期具有固有的难度-特别是当您不知道哪个是较早的日期时。

是否有任何整洁的方法直接计算Date之间的时间差(并将它们再次添加到Date实例中)不使用其{ {1}}?

6 个答案:

答案 0 :(得分:6)

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

extension Date {

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

}

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

let delta = toDate - fromDate

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

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

因此它已经支持

Date + TimeInterval = Date

因此,它也应该支持

Date - Date = TimeInterval
我认为

,这就是我通过-运算符的简单实现添加的内容。现在,我可以简单地按照问题中所述的方式编写示例函数:

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`
     }
}

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

答案 1 :(得分:2)

简单地toDate.timeIntervalSince(fromDate)

要在不添加任何扩展名的情况下重新实现您的功能,

evaluate("INDEX($C$1:$C$8,MAX(($A$1:$A$8=F1)*($C$1:$C$8<>"""")*ROW($A$1:$A$8)),1)")

答案 2 :(得分:2)

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

let delta = toDate.timeIntervalSince(fromDate)

答案 3 :(得分:0)

怎么样……

func computeNewDate(from fromDate: Date, to toDate: Date) -> Date {
    let delta = Calendar.current.dateComponents([.second], from: fromDate, to: toDate).second!
    return Calendar.current.date(byAdding: .second, value: delta, to: Date())!
}

答案 4 :(得分:0)

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

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)
    }

}

使用:

let interval = Date() - updatedDate
print(interval.day)
print(interval.month)
print(interval.hour)

答案 5 :(得分:0)

您可以使用:

let delta = fromDate.distance(to: toDate)