NSDateComponents weekday not showing correct weekday?

I got an NSDate like 1/6 -12 (Friday) and tried to figure out what day of the week it is. My week starts on Monday, so Friday should be 5 weekdays.

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    [calendar setFirstWeekday:2];
    NSDateComponents *components = [calendar components:NSWeekdayCalendarUnit fromDate:firstOfJulyDate];
    NSLog(@"weekday %i",components.weekday);


Exit: weekday 6

It doesn't matter what I set setFirstWeekday for, the output will always be 6. What am I doing wrong?


source to share

3 answers

Try doing something like this:

NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[gregorian setFirstWeekday:2]; // Sunday == 1, Saturday == 7
NSUInteger adjustedWeekdayOrdinal = [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:[NSDate date]];
NSLog(@"Adjusted weekday ordinal: %d", adjustedWeekdayOrdinal);




As the documentation for NSDateComponents says:

Weekday units are numbers from 1 to n, where n is the number of days per week. For example, in the Gregorian calendar, n is 7 and Sunday is 1.

This value is interpreted in the context of the calendar with which it is used - see "Calendars, Date Components, and Calendar Units" in the Date and Time Programming Guide.

And if you look at NSGregorianCalendar as expected, it will define the value 1-7 as Sunday-Saturday.

Calling setFirstWeekday: 2 means your weeks start on Monday, to calculate things like the second week of the month, etc. This does not mean that your Mondays suddenly become Sundays. June 1, 2012 is still Friday and not Thursday, so you get 6 and not 5.

If instead of the day of the week you want to know how many days from the start of the week, this is easy:

(components.weekday - calendar.firstWeekday + 1) % 7




NSDateComponents does not automatically synchronize all components, for example:

NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *component = [calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSWeekdayCalendarUnit fromDate:date];

currentMonth = component.month;

// printing the next 3 month start dates MUST have the setYear! 

for (int i = currentMonth; i < currentMonth + 3; i++) {

    [components setDay:1];
    [components setMonth:i];
    [components setYear:2014];

    NSDate *newDate = [calendar dateFromComponents:components];

    NSDateComponents *components2 = [calendar components:NSDayCalendarUnit |NSMonthCalendarUnit | NSWeekdayCalendarUnit fromDate:newDate];

    monthInt = [components2 month];
    weekIndex = [components2 weekday];


Be sure to enter the code for the date transition to the next year (including a simple if statement before the loop)



All Articles