这个月有多少个工作日

时间:2014-02-25 13:19:23

标签: ios objective-c

获取一个月内的天数很容易,

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

但是如何获得当月的工作日数(周一至周五)?

4 个答案:

答案 0 :(得分:5)

不幸的是,没有直接的方法在两个日期之间循环,你无法直接从NSDate对象获得工作日。因此,您需要添加几行才能使其正常工作。这里的关键是使用NSDateComponents。在这个例子中,我使用的是公历。默认情况下,根据Apple的文档,工作日从周日开始,即第一天(字面意思为1)。请不要认为周日是零(通常会感到困惑)。

可能需要一些语法更改,因为我没有在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);

答案 1 :(得分:4)

让我们看看......如果我们每个月有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;

答案 2 :(得分:1)

如果您愿意,可以使用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;
}

答案 3 :(得分:0)

你几乎就在那里:你已经获得了特定月份的天数(nDays);现在从1循环到nDays,每天找到它的星期几,如果它在星期一和星期五之间,则递增一些计数器。田田,你得到了你想要的东西。