从今天的日期减去周数和天数的小时余数

时间:2016-11-11 15:54:41

标签: ios swift date

参考这个旧的question

我不知道为什么我剩下一小时,从今天开始减去几周和几天。

dump(Date().xWeeks(-13).xDays(-2).elapsedDescription)

extension Date {

    /// Returns a new date that is 'x' number of days hence the recevier.
    public func xDays(_ x:Int) -> Date {
        return Calendar.current.date(byAdding: .day, value: x, to: self)!
    }

    /// Returns a new date that is 'x' number of weeks (of year) hence the recevier.
    public func xWeeks(_ x:Int) -> Date {
        return Calendar.current.date(byAdding: .weekOfYear, value: x, to: self)!
    }

    /// The count of hours hence the receiver. Today's date is established using the device clock.
    public func elapsedHours(toDate: Date) -> Int{
        return Calendar.current.dateComponents([.hour], from: self, to: toDate).hour!
    }

    /// The count of days hence the receiver. Today's date is established using the device clock.
    public func elapsedDays(toDate: Date) -> Int{
        return Calendar.current.dateComponents([.day], from: self, to: toDate).day!
    }

    /// The count of weeks hence the receiver. Today's date is established using the device clock.
    public func elapsedWeeks(toDate: Date) -> Int{
        return Calendar.current.dateComponents([.weekOfYear], from: self, to: toDate).weekOfYear!
    }

    public var elapsedDescription: String {
        let toDate = Date()
        let weekValue = elapsedWeeks(toDate: toDate) == 1 ? "week" : "weeks"
        if elapsedWeeks(toDate: toDate) > 0 {
            let dayRemainder = elapsedDays(toDate: toDate)-elapsedWeeks(toDate: toDate)*7
            if dayRemainder > 0 {
                let dayValue = dayRemainder == 1 ? "day" : "days"
                let remainingHours = elapsedHours(toDate: toDate)-elapsedWeeks(toDate: toDate)*7*24 - (dayRemainder*24)
                if remainingHours > 0 {
                    let hourValue = remainingHours == 1 ? "hour" : "hours"
                    return "\(elapsedWeeks(toDate: toDate)) \(weekValue), \(dayRemainder) \(dayValue) and \(remainingHours) \(hourValue)"
                } else {
                    return "\(elapsedWeeks(toDate: toDate)) \(weekValue) and \(dayRemainder) \(dayValue)"
                }
            } else {
                return "\(elapsedWeeks(toDate: toDate)) \(weekValue)"
            }
        } else if elapsedHours(toDate: toDate) > 0 {
            let hourValue = elapsedHours(toDate: toDate) == 1 ? "hour" : "hours"
            return "\(elapsedHours(toDate: toDate)) \(hourValue)"
        } else {
            return ""
        }
    }

}

1 个答案:

答案 0 :(得分:0)

您的代码假定一天有24小时,但情况并非总是如此。在夏令时的地区,一天可以 23或25小时,向前或向后调整时钟。

在伦敦,DST于10月30日结束,这意味着当天有25个小时。这解释了输出中的额外小时。

正确的解决方案很简单:只需一步计算周,天和小时的差异:

let comps = Calendar.current.dateComponents([.weekOfYear, .day, .hour],
                                            from: self, to: toDate)

然后从

创建所需的输出字符串
comps.weekOfYear!, comps.day!, comps.hour!

在您的示例中,dump(comps)显示

▿ day: 6 hour: 0 weekOfYear: 13 isLeapMonth: false 
  - day: 6
  - hour: 0
  - weekOfYear: 13
  - isLeapMonth: false