How many working days this month

Getting the number of days per month is quite simple,

    NSDate *today = startDate; 
    NSCalendar *c = [NSCalendar currentCalendar];
    NSRange days = [c rangeOfUnit:NSDayCalendarUnit
                           inUnit:NSMonthCalendarUnit
                          forDate:today];

But how do I get the number of working days (Monday - Friday) in the current month?

+3
source share
4 answers

Unfortunately, there is no direct path to the cycle between the two dates, and you cannot get the working day directly from the NSDate object. So you need to add some more lines to make it work. The key point here is the use of NSDateComponents. In this example, I use the Gregorian calendar. By default, according to Apple documentation, weekdays begin on Sunday, which is the first day (literally 1). Please do not assume that Sunday is zero (this is usually confusing).

, XCode

NSInteger count = 0;
NSInteger sunday = 1;
NSInteger saturday = 7;

// Set the incremental interval for each interaction.
NSDateComponents *oneDay = [[NSDateComponents alloc] init];
[oneDay setDay:1];

// Using a Gregorian calendar.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *currentDate = fromDate;

// Iterate from fromDate until toDate
while ([currentDate compare:toDate] == NSOrderedAscending) {

    NSDateComponents *dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:currentDate];

    if (dateComponents.weekday != saturday && dateComponents.weekday != sunday) {
        count++;
    }

    // "Increment" currentDate by one day.
    currentDate = [calendar dateByAddingComponents:oneDay
                                            toDate:currentDate
                                           options:0];
}

NSLog(@"count = %d", count);
+5

... 28 , 4 + , .. 8 . 29,30,31 . :

1   . 28  | 29  30  31
Mon . Sun | Mon Tue Wed
Tue . Mon | Tue Wed Thu
Wed . Tue | Wed Thu Fri
Thu . Wed | Thu Fri SAT
Fri . Thu | Fri SAT SUN
Sat . Fri | SAT SUN Mon
Sun . Sat | SUN Mon Tue

     29 30 31
4 -> +0 +0 +1
5 -> +0 +1 +1
6 -> +1 +1 +0
7 -> +1 +0 +0

#define inRange(x, a, b) ((x) >= (a) && (x) <= (b))

int nDays = <get days in month>;
int firstWeekday = <get first weekday index>;
int nOffDays = 8;

if (nDays > 28 && inRange(firstWeekday, 6, 7)) nOffDays += 1;
if (nDays > 29 && inRange(firstWeekday, 5, 6)) nOffDays += 1;
if (nDays > 30 && inRange(firstWeekday, 4, 5)) nOffDays += 1;

int nWorkDays = nDays - nOffDays;
+4

, NSCalendar - . ,

const NSUInteger Sunday = 1, ....., Saturday = 7;

NSUInteger workdaysCount 
        = getNumberOfDaysInMonth(today)
        - getWeekdayCountInMonth(today, Saturday)
        - getWeekdayCountInMonth(today, Sunday);

:

,

NSUInteger getNumberOfDaysInMonth(NSDate* date) {
    NSCalendar *c = [NSCalendar currentCalendar];
    return [c rangeOfUnit:NSCalendarUnitDay
                   inUnit:NSMonthCalendarUnit
                  forDate:date].length;
}

, NSCalendar :

NSUInteger getWeekdayCountInMonth(NSDate* date, enum Weekdays weekday) {
    NSCalendar *c = [NSCalendar currentCalendar];
    NSDate* startOfMonth = getMonthStart(date);
    NSDate* firstMatchingWeekday = [c dateBySettingUnit:NSWeekdayCalendarUnit value:weekday ofDate:startOfMonth options:0];

    // Number of days from start of month until we are at given weekday
    NSUInteger daysToWeekday = [c components:NSDayCalendarUnit
                                    fromDate:startOfMonth
                                      toDate:firstMatchingWeekday options:0].day;

    NSUInteger days = getNumberOfDaysInMonth(date) - daysToWeekday;

    return (days + 6) / 7;
}
+1

You are almost there: you already have the number of days ( nDays) for a given month; Now the cycle is from 1 to nDaysso that each day finds its day of the week, and if it is between Monday and Friday, increase the counter. Tada, you have what you wanted.

0
source

All Articles