NSDateComponents weekday doesn't show correct weekday?

I got a NSDate for example 1/6 -12 (Friday) and trying to find out what weekday it is. My week starts at Monday so Friday should be weekday 5.

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

Output: weekday 6

Doesn't matter what i set setFirstWeekday to, output will always be 6. What am i doing wrong?

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 the numbers 1 through n, where n is the number of days in the week. For example, in the Gregorian calendar, n is 7 and Sunday is represented by 1.

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

And if you look at NSGregorianCalendar, as expected, it defines the meaning of 1–7 as Sunday–Saturday.

Calling setFirstWeekday:2 means that your weeks start on Monday, for calculating things like whether this is the second week of the month, etc. It doesn't mean your Mondays suddenly become Sundays. 1 Jun 2012 is still a Friday, not a Thursday, so you get 6, not 5.

If, instead of the weekday, you want to know how many days from the start of the week it is, that's easy:

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

NSDateComponents doesn't automatically sync 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's 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 code for the date crossing into the next year (include a simple if statement before the loop)


Need Your Help

How to resolve The type 'xxx' exists both in '[website root]' and 'App_Code' from a MVC view?

c# asp.net asp.net-mvc asp.net-mvc-4 duplicates

I have created a custom identity, principal and membership provider and accessing them through a UserContext class (all sitting in App_code):

Determining Build Directory from SConscript

python build-automation scons

I have an SConscript which is being copied to a build directory (variant_dir = ...) for construction. As a workaround for not being able to express dependencies, I'm trying to copy some additional ...