0

私はiPhoneカウントダウンアプリを作成していますが、ユーザーが設定した日付までに週末(土曜日や日曜日など)が何回発生するかを知る必要があります。

例として、今(8月6日月曜日)から来週までの週末の数をどのように見つけることができますか?答えは1週末ですが、コードを使用してこれを理解できる必要があります。

私が得た最も近いものは、NSDateComponentsとNSCalenderを使用して、次のようなことをすることです。

NSDateComponents *weekendsLeftComponents = [calendar components:NSWeekCalendarUnit
                                                    fromDate:targetDate
                                                      toDate:[NSDate date]
                                                     options:0];

しかし、そこから私は通り過ぎることのない恐ろしいコーダーの壁にぶつかりました。

私の問題は、これを行う方法を正確に知っていることではありません。アレイは機能するように思えますが、これらの「もの」のいくつかは数年もかか​​る可能性があるため、アレイはかなり大きくなる可能性があります。(私は、人が卒業するまでの日数や週末などを調べるアプリを作成しています。)また、私の聴衆は主にiPodを持っている子供から10代、それ以上の年齢の人です。なくなる前に彼らのメモリ(RAM)がどれだけいっぱいになるかわかりません。

よろしくお願いします、

アレックスケーファー

4

2 に答える 2

1

それはあなたのように見え、将来であると仮定して、後方にfromDateあります。toDatetargetDate

これが私がこの問題を解決する方法です。

カテゴリを作成して、NSCalendar2つの日付の間に特定の平日が発生する回数をカウントします。

@interface NSCalendar (AlexCategory)

// The number of times weekday number `weekday` (1 = Sunday, 7 = Saturday)
// occurs between `fromDate` and `toDate`.  If `fromDate` falls on the desired
// weekday, it is counted.  If `toDate` falls on the desired weekday, it is NOT counted.
- (NSInteger)countOfWeekday:(NSInteger)weekday fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate;

@end

この新しいメソッドを実装するために、次の年、月、日、および曜日を取得することから始めますfromDate

@implementation NSCalendar (AlexCategory)

- (NSInteger)countOfWeekday:(NSInteger)weekday fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate {
    NSDateComponents *components = [self components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSWeekdayCalendarUnit fromDate:fromDate];

fromDate次に、次の希望する平日までの日数をカウントします。

    NSInteger daysUntilDesiredWeekday = weekday - components.weekday;
    // If fromDate is a Wednesday and weekday is Monday (for example),
    // daysUntilDesiredWeekday is negative.  Fix that.
    NSRange weekdayRange = [self minimumRangeOfUnit:NSWeekdayCalendarUnit];
    if (daysUntilDesiredWeekday < weekdayRange.location) {
        daysUntilDesiredWeekday += weekdayRange.length;
    }

希望の平日に当たるdaysUntilDesiredWeekdayとゼロになることに注意してください。fromDate

NSDateComponentsこれで、次の日以降の最初の希望する平日を表すを作成できますfromDate

    NSDateComponents *firstDesiredWeekday = [[NSDateComponents alloc] init];
    firstDesiredWeekday.year = components.year;
    firstDesiredWeekday.month = components.month;
    firstDesiredWeekday.day = components.day + daysUntilDesiredWeekday;

最初に希望する平日に更新fromDateし、それ以降の場合は0を返しますtoDate

    fromDate = [self dateFromComponents:firstDesiredWeekday];
    if ([fromDate compare:toDate] != NSOrderedAscending) {
        return 0;
    }

次に、更新fromDateからtoDate:までのすべての日(希望する平日だけでなく)をカウントします。

    NSInteger allDaysCount = [self components:NSDayCalendarUnit
        fromDate:fromDate toDate:toDate options:0].day;

これを1週間の日数で割って、希望する平日の数だけを数えることができます。希望の平日からカウントを開始したため、週の余りには希望の平日も含まれるため、切り上げる必要があります。

    // Adding weekdayRange.length - 1 makes the integer division round up.
    return (allDaysCount + weekdayRange.length - 1) / weekdayRange.length;
}

@end

次のようにメソッドをテストできます。

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

NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = 2012;
components.month = 1;
components.day = 1;
NSDate *fromDate = [calendar dateFromComponents:components];

for (NSUInteger i = 1; i <= 365; ++i) {
    components.day = i;
    NSDate *toDate = [calendar dateFromComponents:components];
    NSLog(@"%@ to %@: %ld Mondays", fromDate, toDate, [calendar countOfWeekday:2 fromDate:fromDate toDate:toDate]);
}

出力は次のように始まります。

2012-08-06 16:27:05.751 tuesdays[81152:403] 0 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-01 06:00:00 +0000
2012-08-06 16:27:05.754 tuesdays[81152:403] 0 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-02 06:00:00 +0000
2012-08-06 16:27:05.756 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-03 06:00:00 +0000
2012-08-06 16:27:05.758 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-04 06:00:00 +0000
2012-08-06 16:27:05.759 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-05 06:00:00 +0000
2012-08-06 16:27:05.760 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-06 06:00:00 +0000
2012-08-06 16:27:05.762 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-07 06:00:00 +0000
2012-08-06 16:27:05.763 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-08 06:00:00 +0000
2012-08-06 16:27:05.763 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-09 06:00:00 +0000
2012-08-06 16:27:05.764 tuesdays[81152:403] 2 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-10 06:00:00 +0000
2012-08-06 16:27:05.765 tuesdays[81152:403] 2 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-11 06:00:00 +0000

これは、次の出力によれば正しいように見えますcal 1 2012

    January 2012
Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

toDateはカウントされないため、2012-1-2は月曜日ですが、2012-1-1から2012-1-2までの月曜日は0です。)

于 2012-08-06T21:29:09.263 に答える
0

問題を特定する必要があります。週末とは何ですか?私にとって週末は土曜日と日曜日です。したがって、日曜日が表示されるたびに週末でした(日曜日は週末全体ではないことに注意してください。要件を単純化したいだけです)。

では、これをコードでどのように行うことができますか?多くの方法があります。簡単な方法の1つは、毎日を含む配列を作成することです[月曜日、火曜日、...、日曜日]

ここで、3週間で今週の火曜日と火曜日の間にいくつの週末が表示されるかを知りたいと思います。を引くと3番目になりますtargetDateComponent.week-currentDateComponent.week。火曜日が3回出現し、すべての日曜日を数えるまで、この配列を調べます。

本当に簡単です。これがあなたの問題を正確に満たしているかどうかはわかりません。しかし、たくさんの方法があります。

慎重に考えてみてください

于 2012-08-06T20:57:26.417 に答える