まず、2つの日付の差components:fromDate:toDate
を返します。したがって、2010-10-01から2010-12-31までの差は91日と予想され、開始日と終了日の両方を含めるために1日を追加する必要があります。
問題は、関数が91日ではなく90日を返すのはなぜですか?
問題は、カレンダー、つまり日付コンポーネントによって使用されるタイムゾーンにあります。デフォルトでは、ローカルタイムゾーンが使用されます。たとえば、ローカルタイムゾーンが「ヨーロッパ/ベルリン」であると仮定します。
その場合、開始日はローカルタイムゾーンで「2010-10-0102:00:00」になります。これは、夏時間が10月の初めにアクティブであり、終了日が2010-12-3101:00:00であるためです。 12月は夏時間がアクティブではないため、ローカルタイムゾーンで。そして、これら2つの日付の違いは、91日ではなく、90日と23時間です。
問題を解決するには、次のいずれかを行うことができます
- ローカルタイムゾーンに従って開始日と終了日を作成する、または
- 差の計算には、タイムゾーンを「GMT」に設定します。
2番目のソリューションの例:
// Create start and end date as in your example:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSDate *startDate = [dateFormatter dateFromString:@"2010-10-01"];
NSDate *endDate = [dateFormatter dateFromString:@"2010-12-31"];
NSLog(@"start=%@", startDate);
NSLog(@"end =%@", endDate);
// Output:
// start=2010-10-01 00:00:00 +0000
// end =2010-12-31 00:00:00 +0000
// Compute difference according to GMT:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDateComponents *components;
components = [gregorian components: NSDayCalendarUnit
fromDate: startDate
toDate: endDate
options: 0];
int days = [components day];
// --> days = 91