user2363025 user2363025 - 6 months ago 378
Swift Question

How to get Monday's date of the current week in swift

I'm trying to get Monday's date of the current week. This is treated as the first day of the week in my table view.
I also need to get Sunday's of the current week. This is treated as the last day of the week in my table view.

Current attempt:

let date = NSDate()
let calendar = NSCalendar.currentCalendar()
calendar.firstWeekday = 1
//attempt to changefirstday

let dateFormatter = NSDateFormatter()
let theDateFormat = NSDateFormatterStyle.ShortStyle
let theTimeFormat = NSDateFormatterStyle.ShortStyle
dateFormatter.dateStyle = theDateFormat
dateFormatter.timeStyle = theTimeFormat

let currentDateComponents = calendar.components([.YearForWeekOfYear, .WeekOfYear ], fromDate: date)
let startOfWeek = calendar.dateFromComponents(currentDateComponents)
print("startOfWeek is \(startOfWeek)")
let stringDate = dateFormatter.stringFromDate(startOfWeek!)
print("string date is \(stringDate)") //This is returning Sunday's date

Answer

Here is a simple function that will give you this week's Monday's date,

func getWeekDaysInEnglish() -> [String] {
    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    calendar.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    return calendar.weekdaySymbols
}

enum SearchDirection {
    case Next
    case Previous

    var calendarOptions: NSCalendarOptions {
        switch self {
            case .Next:
                return .MatchNextTime
            case .Previous:
                return [.SearchBackwards, .MatchNextTime]
        }
    }
}

func get(direction: SearchDirection, _ dayName: String, considerToday consider: Bool = false) -> NSDate {
    let weekdaysName = getWeekDaysInEnglish()

    assert(weekdaysName.contains(dayName), "weekday symbol should be in form \(weekdaysName)")

    let nextWeekDayIndex = weekdaysName.indexOf(dayName)! + 1 // weekday is in form 1 ... 7 where as index is 0 ... 6

    let today = NSDate()

    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!

    if consider && calendar.component(.Weekday, fromDate: today) == nextWeekDayIndex {
        return today
    }

    let nextDateComponent = NSDateComponents()
    nextDateComponent.weekday = nextWeekDayIndex


    let date = calendar.nextDateAfterDate(today, matchingComponents: nextDateComponent, options: direction.calendarOptions)
    return date!
}

get(.Next, "Monday") // Nov 2, 2015, 12:00 AM
get(.Next, "Sunday") // Nov 1, 2015, 12:00 AM

get(.Previous, "Sunday") // Oct 25, 2015, 12:00 AM
get(.Previous, "Monday") // Oct 26, 2015, 12:00 AM

get(.Previous, "Thursday") // Oct 22, 2015, 12:00 AM
get(.Next, "Thursday") // Nov 5, 2015, 12:00 AM
get(.Previous, "Thursday", considerToday:  true) // // Oct 29, 2015, 12:00 AM

You can use this method to get any days and day name you provide to the function should be either of these,

"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"