Jack Stark
Jack Stark

Reputation: 77

How to find the next weekday or weekend using swift?

I found this old post regarding how to find the next Monday, Tuesday... etc. This is helpful, but what if we want to find next weekday or weekend? The next weekend might be Saturday, or it might be Sunday, so now what should I do to let the code decide for us? (That goes similarly to find the next weekday, which has 5 choices based on the current date).

Any help would work. Is there a way to modify the existing extension I mentioned before in the old post?

Upvotes: 0

Views: 1762

Answers (3)

Ben Kennedy
Ben Kennedy

Reputation: 288

Leveraging Calendar’s isDateInWeekend(), finding the next weekday following a given date is straightforward:

func nextWeekday(after date: Date,
                 in calendar: Calendar) -> Date {
    var components = calendar.dateComponents([.year, .month, .day],
                                             from: date)
    var nextDate: Date!
    repeat {
        components.day! += 1
        nextDate = calendar.date(from: components)
    } while calendar.isDateInWeekend(nextDate)
    
    return nextDate
}
let calendar = Calendar.current
let date = calendar.date(from: DateComponents(year: 2022, month: 10, day: 28))!
// Fri 2022-10-28 07:00:00 UTC
let nextDate = nextWeekday(after: date, in: calendar)
// Mon 2022-10-31 07:00:00 UTC

Upvotes: 0

valeCocoa
valeCocoa

Reputation: 344

You might as well leverage on enumerateDates(startingAfter:matchingPolicy:using) Calendar's method:

extension Calendar {
    enum KindOfDay {
        case weekend
        case weekday
        
    }
    
    func next(_ kind: KindOfDay) -> Date? {
        let now = Date.init(timeIntervalSinceNow: 0)
        let dc = DateComponents(hour: 0, minute: 0, second: 0)
        
        var result: Date?
        enumerateDates(startingAfter: now, matching: dc, matchingPolicy: .nextTime, using: { candidate, _, stop in
            guard
                let candidate = candidate
            else {
                stop = true
                return
            }
            
            let isWeekend = isDateInWeekend(candidate)
            stop = kind == .weekend ? isWeekend : !isWeekend
            result = stop ? candidate : nil
        })
        
        return result
    }
    
}

Upvotes: 0

El Tomato
El Tomato

Reputation: 6707

Finding the date for the next weekend is simple.

let now = Date()
if let timeInterval = cal.nextWeekend(startingAfter: now, direction: .forward) {
    let startDate = timeInterval.start
    let endDate = timeInterval.end
    print(startDate, endDate)
}

nextWeekend(startingAfter:direction:) does not return a specific Date object. It returns a DateInterval object, instead.

Finding the next date for any of week days is a challenge. That's because it can be Monday, Tuesday, Wednesday, Thursday or Friday. The following is how to find the next Monday.

let cal = Calendar.current
var comps = DateComponents()
comps.weekday = 2
let now = Date()
if let nextMonday = cal.nextDate(after: now, matching: comps, matchingPolicy: .nextTimePreservingSmallerComponents) {
    print(nextMonday)
}

, where 2 is for Monday.

Upvotes: 2

Related Questions