3

Objective C で今月の火曜日の数を計算する方法を探しています。

たとえば、コードが今日 (2012 年 7 月 16 日) 実行された場合、2012 年の 7 月には 5 つの火曜日 (3 日、10 日、17 日、24 日、31 日) があるため、5 が出力されます。

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];

これで、2 つの日付の間の日数を求めることができます。

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

ほとんどの週には 7 日と 1 回の火曜日があるため、日数を 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 2012cal 2011、およびの出力を見てcal 2000、いくつかの結論を導き出しました。

毎月4回か5回の火曜日があります。

火曜日が 5 回ある月を見つけるには、次の点に注意してください。

  • 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 に答える