Tieme
Tieme

Reputation: 65379

NSDateComponents returns wrong weekday

If you'll run this code:

// January 16th 2015 10:20 AM in Amsterdam
var date = NSDate(timeIntervalSince1970: 1421400000)

var formatter = NSDateFormatter()
formatter.dateFormat = "dd-MMM"

let calendar = NSCalendar.currentCalendar()
calendar.firstWeekday = 2 // default when region == Netherlands

let units = NSCalendarUnit.YearCalendarUnit | NSCalendarUnit.MonthCalendarUnit
    | NSCalendarUnit.WeekOfMonthCalendarUnit | NSCalendarUnit.DayCalendarUnit
    | NSCalendarUnit.WeekdayCalendarUnit

// Loop days in January
for day in 1...14 {

    // select day in month
    var components = calendar.components(units, fromDate: date)
    components.day = day

    // get day and components
    let _date = calendar.dateFromComponents(components)!
    var _components = calendar.components(units, fromDate: _date)

    // retrieve characteristics
    let weekOfMonth = _components.weekOfMonth
    let dayOfWeek = _components.weekday
    let month = _components.month

    println("\(formatter.stringFromDate(_date)) is day \(dayOfWeek) of week \(weekOfMonth) of month \(month) \n")
}

You'll probably get back:

01-Jan is day 5 of week 1 of month 1
02-Jan is day 6 of week 1 of month 1
03-Jan is day 7 of week 1 of month 1
04-Jan is day 1 of week 1 of month 1
05-Jan is day 2 of week 2 of month 1
06-Jan is day 3 of week 2 of month 1
07-Jan is day 4 of week 2 of month 1
.... 

Those weekdays are wrong.

Not only should the the 1st of january be the 4th day (a thursday), it's also strange that the 3rd of january seems to be on day 7 of week 1 and the 4th of january seems to be day 1 of that same week.

Obviously I'm doing something wrong here, who could help me out?

When you remove the calendar.firstWeekday = 2 line you'll get:

01-Jan is day 5 of week 1 of month 1
02-Jan is day 6 of week 1 of month 1
03-Jan is day 7 of week 1 of month 1
04-Jan is day 1 of week 2 of month 1
05-Jan is day 2 of week 2 of month 1
06-Jan is day 3 of week 2 of month 1
07-Jan is day 4 of week 2 of month 1
....

That makes more sense, but I really need the first day of the week to be a monday here..

I've set up a demo project for you to test this behaviour yourself. https://github.com/tiemevanveen/NSDateComponentsTest/tree/master


As sha points out, components.weekday does not change if your week does not start on a sSnday. Strange that components.weekOfMonth does change when your week starts on Monday..

Solution to my problem

An answer to another question let me to a way to find the desired weekday if the calendar's week does not start with a Sunday.

dayOfWeek = calendar.ordinalityOfUnit(.WeekdayCalendarUnit, inUnit: .WeekCalendarUnit, forDate: _date)

That code could also be used to find the week of the month or the month itself:

dayOfWeek = calendar.ordinalityOfUnit(.WeekdayCalendarUnit, inUnit: .WeekCalendarUnit, forDate: _date)
month = calendar.ordinalityOfUnit(.MonthCalendarUnit, inUnit: .YearCalendarUnit, forDate: _date)

Upvotes: 2

Views: 3448

Answers (1)

sha
sha

Reputation: 17860

It's all correct. If you look at Apple Documentation. you can see that 1 is Sunday, 2 - is Monday and so forth. So 5 is Thursday as expected.

Upvotes: 5

Related Questions