Search code examples
iosnsdatenscalendar

getting work days of week


I am working on a student schedule and i have a problem. I need to have an array of days of current week, and of next week. So if today is Tue 11.11 i need to somehow get Mon 10.11 Tue 11.11 Wed 12.11 Thurs 13.11 Friday 14.11, and the same days of the next week with it dates. This one i need to do in my program such function, when user can pick any day of week and set his schedule on this day. I looked everywhere on stack overflow, but all solutions was not exact. Can you help me? Here is some of my attempts.

NSDate *now = [NSDate date];

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *beginningOfThisWeek;
NSDate *beginningOfNextWeek;

NSTimeInterval durationOfWeek;
[calendar setFirstWeekday:3];
[calendar rangeOfUnit:NSCalendarUnitWeekOfMonth
            startDate:&beginningOfThisWeek
             interval:&durationOfWeek
              forDate:now];

beginningOfNextWeek = [beginningOfThisWeek dateByAddingTimeInterval:durationOfWeek];


NSDate *date = beginningOfThisWeek;
NSMutableArray *dateArray = [@[] mutableCopy];

while (![beginningOfNextWeek compare:date]  == NSOrderedSame) {
    [dateArray addObject:date];
    NSDateComponents *comps = [calendar components:NSUIntegerMax fromDate:date];
    comps.day +=1;
    date = [calendar dateFromComponents:comps];

}
NSLog(@"%@",dateArray);
NSLog(@"%@",now);

but in log i get something like:

2014-11-11 18:37:29.479 StudentSchedule[3964:436389] (
    "2014-11-10 22:00:00 +0000",
    "2014-11-11 22:00:00 +0000",
    "2014-11-12 22:00:00 +0000",
    "2014-11-13 22:00:00 +0000",
    "2014-11-14 22:00:00 +0000",
    "2014-11-15 22:00:00 +0000",
    "2014-11-16 22:00:00 +0000"

i have dates, but 7, and i don't have names of weekdays, which is very important. I know that my question is very simple, but i am tired of looking for the right answer.


Solution

  • OK, so say you open the app on a certain day.

    You want all of the working days (Monday to Friday) for that week and all of the working days for next week also.

    Right...

    - (void)getDays
    {
        NSArray *days = @[];
    
        NSDate *currentDate = [NSDate date];
    
        // add this week's work days to array
        days = [days arrayByAddingObjectsFromArray:[self workDaysOfWeekFromDate:currentDate]];
    
        NSDate *nextWeek = [self dateWeekAfterDate:currentDate];
    
        // add next week's work days to array
        days = [days arrayByAddingObjectsFromArray:[self workDaysOfWeekFromDate:nextWeek]];
    }
    
    - (NSDate *)dateWeekAfterDate:(NSDate *)date
    {
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        NSDateComponents *components = [NSDateComponents new];
        components.day = 7;
    
        return [calendar dateByAddingComponents:components toDate:date options:0];
    }
    
    - (NSInteger)dayOfWeekFromDate:(NSDate *)date
    {
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        NSDateComponents *components = [calendar components:NSCalendarWeekdayUnit fromDate:date];
    
        return components.weekday;
    }
    
    - (NSDate *)dayWithIndex:(NSInteger)dayIndex fromWeekOfDate:(NSDate *)date
    {
        NSInteger dayOfWeekFromDate = [self dayOfWeekFromDate:date];
    
        NSInteger difference = dayIndex - dayOfWeekFromDate;
    
        NSDateComponents *components = [NSDateComponents new];
        components.day = difference;
    
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        return [calendar dateByAddingComponents:components toDate:date options:0];
    }
    
    - (NSArray *)workDaysOfWeekFromDate:(NSDate *)date
    {
        // Sunday = 1
        // ...
        // Saturday = 7
    
        return @[
            [self dayWithIndex:2 fromWeekOfDate:date], // Monday
            [self dayWithIndex:3 fromWeekOfDate:date], // Tuesday
            [self dayWithIndex:4 fromWeekOfDate:date], // Wednesday
            [self dayWithIndex:5 fromWeekOfDate:date], // Thursday
            [self dayWithIndex:6 fromWeekOfDate:date]  // Friday
        ];    
    }
    

    There are several functions here. Everything happens and is finished in the getDays function. When that finishes the array days will contain NSDate objects for Monday-Friday this week and next week.

    Of course, you can change the currentDate to be any date you want. It will always take the week from currentDate and the week after currentDate.

    This will always work, with any calendar and leap years etc...

    For getting the names of the dates you can do this...

    NSDate *date = [NSDate date];
    
    NSDateFormatter *df = [NSDateFormatter new];
    df.dateFormat = @"EEEE";
    
    NSString *dayName = [df stringFromDate:date];
    

    The format EEEE means the day name. So today the dayName string is Tuesday.

    EEEE = Tuesday
    EEE = Tue
    

    You could of course merge this down into one function which would have fewer lines. But I prefer having readable code.