私の答えは少し長くなり、おそらく少しOTになりますが、「コピーアンドペースト」の答えではなく、日付管理の概念に関する知識を提供する方がよいと思います. 直感的であっても、実際には日付管理は非常に複雑な作業です。Cocoa でこれを適切に行うには、いくつかの基本的な概念を理解する必要があります。
「日付」の概念自体は、基準日から何秒経過したかを数値で表したものにすぎません。これは絶対的な尺度であり、何も変更することはできません。現在が時間 0 であると言うと、10 秒後には時間 10 になります。「NSDate」を持つCocoaで表されます。
「数値日付」を「カレンダー日付」に変換するには、この数値日付を「カレンダー」(「NSCalendar」Cocoa クラス) に適用する必要があります。明らかに多くの種類のカレンダーがあるため、使用する適切なカレンダーを選択し、それに数値の日付を適用する必要があります。有効な結果は「カレンダー化された日付」になります。絶対的な尺度であるため、すべてのカレンダーに共通の同じ「数値日付」でも、異なるカレンダーでは異なる結果が得られることに注意してください。カレンダーはすべて、すべての単一の数値日付を特定の「カレンダー日付」にマップする複雑なアルゴリズムまたはテーブルです。
カレンダーの日付を構成するコンポーネントは「日付コンポーネント」と呼ばれ、Cocoa クラスの「NSDateComponents」で表されます。ご存じかもしれませんが、「日付コンポーネント」と「日付」を直接関連付けることはできませんが、「カレンダー」を介してそれらを仲介する必要があります。そのため、「Date」クラスと「NSDateComponents」クラスを関連付けるすべてのメソッドが「NSCalendar」クラスで定義されています。これは、特定の「NSDateComponents」インスタンスが特定の「NSCalendar」インスタンスに関連付けられている理由を説明しています。
最後に、「日付コンポーネント」を「人間が読める形式」に変換します。これを行うには、「NSDateFormatter」オブジェクトを使用します。日付フォーマッタを日付コンポーネントにリンクする方が適切ですが、日付から文字列への変換、およびその逆の変換を容易にするために、NSDateFormatter メソッドは NSDateComponents ではなく NSDate オブジェクトを直接操作します。明らかに、NSDateFormatter クラスは特定のカレンダーに関連付ける必要があります (注意してください: デフォルトのカレンダーで初期化されます)。
これで、この情報の荷物ができたので、続行する方法を簡単に理解できます。あなたの仕事は、「文字列形式」の日付を、10 日後の同じ形式の日付に変換することです。したがって、実行するタスクは次のとおりです (コードは以下のとおりです)。
1. identify the Calendar you want to use
2. create a NSDateFormatter that accepts your input string and link the Calendar to it
3. use NSDateFormatter to import the string to a "NSDate"
4. use the NSCalendar to convert the date to a NSDateComponents object
5. add 10 days to the "day" component of NSDateComponents; don't take care of "end of month" or "end of year", because NSDateComponents + NSCalendar know how to do it!
6. use NSCalendar again to convert the new recalculated NSDateComponents instance to NSDate
7. use the NSDateFormatter you defined before to convert the new NSDate to a NSString.
あなたは疑問に思うかもしれません: インポートした NSDate の 10*24*60*60 秒を合計できないのはなぜですか? ほとんどの場合、この解決策は機能しますが、この操作によって誤った結果が得られる場合があります。たとえば、夏時間の切り替えでは、時計を 1 時間戻します。つまり、60*60 = 3600 秒です。これは、カレンダーで 1 時間の範囲の秒が 2 つの異なる日時 (切り替えの 1 時間前と 1 時間後) にマップされることを意味します。この情報は NSDate にはわかりませんが、NSCalendar にはわかります。このようにして何が起こっているかを視覚的に確認できます: 無限に長い線 (時間の線) を想像してみてください。線のすべての「刻み」は 1 秒です。現在いる「時点」を維持すると、この目盛りはカレンダーと時計の特定の日時に関連付けられます。このタイムラインで夏時間の切り替えを行うポイントを特定し、その時点で時計を 1 時間前に戻す必要があるとします。タイムラインを 2 つに分けて、後半を取り、最初の 1 時間と前半の最後の 1 時間を重ねます。その後、時間はまだ進行中であることがわかりますが、この 1 時間のオーバーラップのカレンダーは、2 つの特定の時間範囲に関連付けられます! これは、NSDate だけではなく、カレンダー + ロケール + タイム ゾーンのみが知っている情報です (ちなみに、「タイム ゾーン」と「ロケール」に関するここでの説明は意図的にスキップしました。絶対時間を有効な時刻に関連付けますが、ロケールは一部のカレンダー規則 (夏時間の切り替えなど) を変更できます)。
NSString *startDateStr = @"2013-02-25";
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.calendar=calendar;
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSDate *startDate = [dateFormatter dateFromString:startDateStr];
NSDateComponents *startComponents = [calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:startDate];
startComponents.day+=10;
NSDate *endDate = [calendar dateFromComponents:startComponents];
NSString *endDateStr = [dateFormatter stringFromDate:endDate];
NSLog(@"Date %@ + 10 days gives %@",startDateStr,endDateStr);
上記の計算は NSCalendar を使用して単純化することもできますがdateByAddingComponents:toDate:options:
、クラス間の相互作用をよりよく把握するために、最初の方法を使用することをお勧めします。