How do I find the beginning of the week from an NSDate?

You can implement this as Date class extension or something. It should returns something like 2020-01-06 00:00:00 +0000

Xcode 11.3 Swift 5

func firstDayOfWeek() -> Date {
    var c = Calendar(identifier: .iso8601)
    c.timeZone = TimeZone(secondsFromGMT: 0)!
    print(
        c.date(from: c.dateComponents([.weekOfYear, .yearForWeekOfYear], from: Date()))!
    )
} 

Swift 4 Solution

I have figured out according to my requirement, where I have find out dates for following.

1. Today

2. Tomorrow 

3. This Week 

4. This Weekend 

5. Next Week 

6. Next Weekend

So, I have created Date Extension to get Dates of Current Week and Next Week.

CODE

extension Date {

    func getWeekDates() -> (thisWeek:[Date],nextWeek:[Date]) {
        var tuple: (thisWeek:[Date],nextWeek:[Date])
        var arrThisWeek: [Date] = []
        for i in 0..<7 {
            arrThisWeek.append(Calendar.current.date(byAdding: .day, value: i, to: startOfWeek)!)
        }
        var arrNextWeek: [Date] = []
        for i in 1...7 {
            arrNextWeek.append(Calendar.current.date(byAdding: .day, value: i, to: arrThisWeek.last!)!)
        }
        tuple = (thisWeek: arrThisWeek,nextWeek: arrNextWeek)
        return tuple
    }

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

    var startOfWeek: Date {
        let gregorian = Calendar(identifier: .gregorian)
        let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
        return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
    }

    func toDate(format: String) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = format
        return formatter.string(from: self)
    }
}

USAGE:

let arrWeekDates = Date().getWeekDates() // Get dates of Current and Next week.
let dateFormat = "MMM dd" // Date format
let thisMon = arrWeekDates.thisWeek.first!.toDate(format: dateFormat)
let thisSat = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 2].toDate(format: dateFormat)
let thisSun = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 1].toDate(format: dateFormat)

let nextMon = arrWeekDates.nextWeek.first!.toDate(format: dateFormat)
let nextSat = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 2].toDate(format: dateFormat)
let nextSun = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 1].toDate(format: dateFormat)

print("Today: \(Date().toDate(format: dateFormat))") // Sep 26
print("Tomorrow: \(Date().tomorrow.toDate(format: dateFormat))") // Sep 27
print("This Week: \(thisMon) - \(thisSun)") // Sep 24 - Sep 30
print("This Weekend: \(thisSat) - \(thisSun)") // Sep 29 - Sep 30
print("Next Week: \(nextMon) - \(nextSun)") // Oct 01 - Oct 07
print("Next Weekend: \(nextSat) - \(nextSun)") // Oct 06 - Oct 07

You can modify Extension according to your need.

Thanks!


you can use Calendar method date(from: DateComponents) passing [.yearForWeekOfYear, .weekOfYear] components from any date it will return the first day of the week from the calendar used. So if you would like to get Sunday just use Gregorian calendar. If you would like to get the Monday as the first day of the week you can use Calendar .iso8601 as you can see in this answer

Xcode 12 • Swift 5.3 or later (works with previous Swift versions as well)

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

extension Date {
    func startOfWeek(using calendar: Calendar = .gregorian) -> Date {
        calendar.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
    }
}

usage:

Date().startOfWeek()  // "Sep 20, 2020 at 12:00 AM"


If you would like to get the beginning of week at a particular timezone you just need to use a custom calendar:

var gregorianUTC = Calendar.gregorian
gregorianUTC.timeZone = TimeZone(identifier: "UTC")!
print(Date().startOfWeek(using: gregorianUTC))  // "2020-09-20 00:00:00 +0000\n"