3

我正在寻找一种方法来计算Objective C中当月星期二的数量。

例如,如果代码在今天(2012 年 7 月 16 日)运行,它将输出 5,因为 2012 年 7 月有 5 个星期二(第 3、10、17、24 和 31 日)。

我已经在 Excel 中看到了在线解决方案,但我正在努力将其转换为 Objective C。

谢谢你的帮助!好久不见,第一次。

4

3 回答 3

6

我们需要一个日历:

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

现在让我们获取当前月份和年份:

    NSDate *now = [NSDate date];
    NSDateComponents *monthAndYear = [calendar components:NSMonthCalendarUnit | NSYearCalendarUnit fromDate:now];

我们可以使用它来获取当前月份和年份的第一个星期二:

    NSDateComponents *firstTuesdayComponents = [monthAndYear copy];
    firstTuesdayComponents.weekday = 3; // Sunday = 1
    firstTuesdayComponents.weekdayOrdinal = 1; // First Tuesday
    NSDate *firstTuesday = [calendar dateFromComponents:firstTuesdayComponents];

我们也可以用它来获取下个月的第一天:

    NSDateComponents *firstOfNextMonthComponents = [monthAndYear copy];
    firstOfNextMonthComponents.month += 1;
    firstOfNextMonthComponents.day = 1;
    NSDate *firstOfNextMonth = [calendar dateFromComponents:firstOfNextMonthComponents];

现在我们可以询问两个日期之间的天数:

    NSDateComponents *differenceComponents = [calendar components:NSDayCalendarUnit fromDate:firstTuesday toDate:firstOfNextMonth options:0];

大多数星期有 7 天和一个星期二,因此我们应该将天数除以 7。如果有余数,我们应该将其四舍五入,因为我们是从星期二开始计算的。

    int tuesdayCount = (differenceComponents.day + 6) / 7; // Adding 6 makes the integer division round up.
    NSLog(@"There are %d Tuesdays in month %d of year %d.", tuesdayCount, (int)monthAndYear.month, (int)monthAndYear.year);

现在让我们跳进时间机器来测试它:

There are 5 Tuesdays in month 1 of year 2012.
There are 4 Tuesdays in month 2 of year 2012.
There are 4 Tuesdays in month 3 of year 2012.
There are 4 Tuesdays in month 4 of year 2012.
There are 5 Tuesdays in month 5 of year 2012.
There are 4 Tuesdays in month 6 of year 2012.
There are 5 Tuesdays in month 7 of year 2012.
There are 4 Tuesdays in month 8 of year 2012.
There are 4 Tuesdays in month 9 of year 2012.
There are 5 Tuesdays in month 10 of year 2012.
There are 4 Tuesdays in month 11 of year 2012.
There are 4 Tuesdays in month 12 of year 2012.
于 2012-07-17T03:27:14.633 回答
1

在查看 、和的输出时cal 2012,我得出了一些结论:cal 2011cal 2000

每个月有四个或五个星期二。

要查找有五个星期二的月份,请注意:

  • 对于有 31 天的月份,第一个必须在星期日、星期一或星期二
  • 对于有 30 天的月份,第一个必须在星期一或星期二
  • 对于有 29 天的月份,第一个必须在星期二

希望这是一个更容易解决的问题。

于 2012-07-17T02:38:58.910 回答
0

使用基于萨诺德在他的回答中所做的相同观察的算法,这应该可以解决问题:

- (NSUInteger)numberOfTuesdaysInMonthContainingDate:(NSDate *)date
{
    NSCalendar *calendar = [NSCalendar currentCalendar];

    NSUInteger numDaysInMonth = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date].length;

    NSDate *firstDayOfMonth;
    NSTimeInterval firstDayOfMonthLength;
    if (![calendar rangeOfUnit:NSMonthCalendarUnit startDate:&firstDayOfMonth interval:&firstDayOfMonthLength forDate:date]) {
        NSLog(@"Unable to calculate first day of the month for %@", date);
        return 0;
    }

    NSUInteger firstDayOfTheMonthWeekday = [calendar ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:firstDayOfMonth];

    // The following is for Tuesday only, the math is more complex for an abitrary weekday
    NSUInteger numTuesdays = 4;
    NSUInteger minValidWeekday = 32 - numDaysInMonth; 
    if (firstDayOfTheMonthWeekday >= minValidWeekday && firstDayOfTheMonthWeekday <= 3) {
        numTuesdays = 5;
    }

    return numTuesdays;
}
于 2012-07-17T03:27:51.257 回答