0
votes

I'm looking to extend the NSDate class so I am able to reference the Tuesday of each week we're currently in as an NSDate.

I understand that this can be done with NSDateComponents. So far I have the below:

extension NSDate {

var tuesday: NSDate {

    let calendar = NSCalendar.currentCalendar()

    let todaysDate = NSDate()

    let weekdayComponents = calendar.components(.CalendarUnitWeekday | .CalendarUnitWeekdayOrdinal, fromDate: todaysDate)

    weekdayComponents.weekday = 3

    let returnTuesday = calendar.dateByAddingComponents(weekdayComponents, toDate: todaysDate, options: nil)

    return returnTuesday!
}}

I believe that the CalendarUnitWeekday work on an index based system (i.e. Sunday = 1, Saturday = 7), which is why I am setting the required weekday to 3 for Tuesday.

However when initialising an NSDate object and accessing this extended 'tuesday' property, I am receiving a date a month in advance.

(todays date - "Aug 26, 2015, 4:42 PM") (tuesday date - "Sep 26, 2015, 4:42 PM")

What is causing this advancement of a month? Is there a way to return a specific date of each week we are in through extending the NSDate class?

Thanks

2

2 Answers

1
votes

Rather than using dateByAddingComponents: you can find today's weekday and get its difference with the target weekday and update the day component. The required date can be generated by dateFomComponents method using the updated components parameter.

extension NSDate {

    var tuesday: NSDate {

        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components(.CalendarUnitWeekday | .CalendarUnitDay | .CalendarUnitMonth | .CalendarUnitYear | .CalendarUnitHour | .CalendarUnitMinute, fromDate: NSDate())
        let targetDay = 3 //Required day
        let today = components.weekday

        if (targetDay < today) {
            components.day -= today - targetDay
        } else {
            components.day += targetDay - today
        }

        return calendar.dateFromComponents(components)!
    }}
0
votes

You're using dateByAddingComponents which is going to take the date provided and add a number of time units to it based on the date components. Those date components have been requested as CalendarUnitWeekday and CalendarUnitWeekdayOrdinal. You have explicitly set one of these to 3 and the other is set to whatever the current date is. So, when you add them, you aren't setting the weekday to 3, you're adding 3 to the week day (probably, I'm not even sure adding a week day to a date makes sense so it might not do this - it may be logical why you move by a month, it may not...) and another value to the week day ordinal. This obviously isn't what you want.

Instead, you should be finding out the current week day and adding / subtracting days until you get to the first next or previous Tuesday. Then, once you're there, you can sanely add days / weeks to this date to get any other required dates.