Search code examples
iosswiftnsdatensdateformatternsdatecomponentsformatter

Exclude dates from date calculation


I'm looking to calculate the time in between 2 dates. I've been using DateComponentsFormatter, which works great for outputting properly in all languages/regions/calendars.

I'd like to add the ability to exclude weekends from this calculation. It doesn't seem to support this natively. Is there a good alternative (native or 3rd party libraries) to remove a set of dates from the calculation?


Solution

  • You can perform this type of calculation natively using the Calendar API; you're just going to have to write it manually:

    import Foundation
    
    // The nextWeekend API is available only on 10.12 or later.
    if #available(OSX 10.12, *) {
    
    let calendar = Calendar(identifier: .gregorian)
    let start = calendar.date(from: DateComponents(year: 2018, month: 3, day: 18))!
    let end   = calendar.date(from: DateComponents(year: 2018, month: 4, day: 7))!
    
    var total: TimeInterval = 0
    
    // We'll iterate weekends from now until the target end date,
    // adding the intervening time from during the week.
    var current = start
    while current < end {
        guard let weekend = calendar.nextWeekend(startingAfter: current) else {
            break
        }
    
        if weekend.start > end {
            // Our target end date is before the next weekend; add whatever time is left.
            total += end.timeIntervalSince(current)
            break
        } else {
            // There's >= 1 weekend between now and the target date; add the week in between.
            total += weekend.start.timeIntervalSince(current)
            current = weekend.end
        }
    }
    
    let formatter = DateComponentsFormatter()
    formatter.allowedUnits = .day
    print(formatter.string(from: total)!) // => 16d
    
    }