Search code examples
objective-cnscalendar

NSCalendar returns the wrong day of the week


I have this code that takes the name of the weekday with the values ​​that are provided, today is August 10, 2014 and should return Sunday, but the code is returning Tuesday, why?

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

        NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
        [dateComponents setWeekday:10];
        [dateComponents setWeekdayOrdinal:1];
        [dateComponents setYear:2014];
        [dateComponents setMonth:8];

        NSDate *tempDate = [gregorian dateFromComponents:dateComponents];

        NSDateFormatter *format = [[NSDateFormatter alloc] init];
        [format setDateFormat:@"EEEE"];

        NSString *retval = [format stringFromDate:tempDate];

        NSLog(@"Today -> %@",retval);

Solution

  • There are couple of problems with your code. First of all weekday property can be a number from 1 to 7 in case of the gregorian calendar.

    From NSDateComponents documentation:

    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.

    So if you want to create NSDateComponents which represent sunday you have to set weekDay property value to 1.

    You have to change value of the weekdayOrdinal property too.

    From NSDateComponents documentation:

    Weekday ordinal units represent the position of the weekday within the next larger calendar unit, such as the month. For example, 2 is the weekday ordinal unit for the second Friday of the month.

    In you case you have to set its value to 2 because you want to create NSDateComponents for the second Sunday of the month.

    Here is changed code:

    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    [dateComponents setWeekday:1];
    [dateComponents setWeekdayOrdinal:2];
    [dateComponents setYear:2014];
    [dateComponents setMonth:8];
    

    That being said, it is probably simple to just use day property and forget about weekday and weekdayOrdinal properties at all:

    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    [dateComponents setDay:10];
    [dateComponents setYear:2014];
    [dateComponents setMonth:8];