计算2个NSDates之间的工作日和周末

Calculate business days and weekend days between 2 NSDates

我正在尝试计算 2 个 NSDate 之间的工作日 + 工作日数量,但我似乎找不到合适的解决方案。我目前可以像这样找到 2 个 NSDate 之间的天数:

func reloadData(){
    let cal = NSCalendar.currentCalendar()

    var daysInt = 0

    let days = cal.components(.Day, fromDate: selectedDateTimePointTwo, toDate: selectedDateTimePointOne, options: [])
    daysInt = days.day

    workDaysLabel.text = "work days: \(daysInt)"
    weekendDaysLabel.text = "weekend days: "
}

谁能指出我正确的方向?

首先,如果你使用的是Swift2,你应该使NSDate符合Comparable协议:

extension NSDate: Comparable { }

public func <(lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.compare(rhs) == .OrderedAscending
}

其次,您可以使用 Calendar isDateInWeekend 来检查是否有任何日期是周末,并且您可以使用 dateByAddingUnit 在开始日期和结束日期之间添加一天:

创建这些扩展来帮助您:

edit/update: Swift 4

extension Calendar {
    static let iso8601 = Calendar(identifier: .iso8601)
}


extension Date {
    var isDateInWeekend: Bool {
        return Calendar.iso8601.isDateInWeekend(self)
    }
    var tomorrow: Date {
        return Calendar.iso8601.date(byAdding: .day, value: 1, to: noon)!
    }
    var noon: Date {
        return Calendar.iso8601.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
    }
}

以及计算天数的方法:

func coutDays(from start: Date, to end: Date) -> (weekendDays: Int, workingDays: Int) {
    guard start < end else { return (0,0) }
    var weekendDays = 0
    var workingDays = 0
    var date = start.noon
    repeat {
        if date.isDateInWeekend {
            weekendDays +=  1
        } else {
            workingDays += 1
        }
        date = date.tomorrow
    } while date < end
    return (weekendDays, workingDays)
}

测试:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let start = DateComponents(calendar: .iso8601, year: 2016).date!  // "Jan 1, 2016, 12:00 AM"
        let end = DateComponents(calendar: .iso8601, year: 2017).date!  // "Jan 1, 2017, 12:00 AM"
        print(coutDays(from: start, to: end))  // 105, 261
    }
}

这里是Swift5版本。我还使用了当前设备日历而不是 iso

func nextDay(in calendar: Calendar) -> Date? {
    return calendar.date(byAdding: .day, value: 1, to: self)
}

func daysCount(until endDate: Date) -> (workingDays: Int, weekends: Int) {
    let calendar = Calendar.current
    var weekends = 0
    var workingDays = 0
    var date = self
    while date < endDate {
        if calendar.isDateInWeekend(date) {
            weekends += 1
        } else {
            workingDays += 1
        }

        guard let nextDay = date.nextDay(in: calendar) else {
            fatalError("Failed to instantiate a next day")
        }

        date = nextDay
    }

    return (workingDays, weekends)
}