计算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)
}
我正在尝试计算 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)
}