8

ここで、2 つの日付の日数差を計算するコードを見つけました。
メソッドを書きます:

-(NSInteger)daysWithinEraFromDate:(NSDate *) startDate toDate:(NSDate *) endDate
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSGregorianCalendar];
    NSInteger startDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                            inUnit: NSEraCalendarUnit forDate:startDate];
    NSInteger endDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                          inUnit: NSEraCalendarUnit forDate:endDate];
    return endDay-startDay;
}

この方法には問題があります。タイムゾーンを考慮できません。私もこのような行を追加します:

[gregorian setTimeZone:[NSTimeZone localTimeZone]];

私のテストコードは次のようなものです:

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *strDate = @"2012-09-03 23:00:00";
    NSDate *dateStart = [dateFormat dateFromString:strDate];
    strDate = @"2012-09-04 01:00:00";
    NSDate *dateEnd = [dateFormat dateFromString:strDate];
    NSLog(@"Days difference between %@ and %@  is:  %d days",[dateFormat stringFromDate:dateStart],[dateFormat stringFromDate:dateEnd],[self daysWithinEraFromDate:dateStart toDate:dateEnd]);

結果は次のとおりです。

2012-09-03 23:00:00 と 2012-09-04 01:00:00 の日数差: 0 日

2 つの日付の間の真夜中の数によって、結果として 1 日を取得したいと考えています。私のタイムゾーンは GMT +8 です。しかし、この計算は GMT に基づいているため、間違った日数を取得します。とにかくこの問題を解決する方法はありますか? ありがとうございました。


Scott Lemmonの方法は、私の問題を解決できます。コードを次のように書き直します。

-(NSInteger)daysWithinEraFromDate:(NSDate *) startDate toDate:(NSDate *) endDate
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSGregorianCalendar];
    [gregorian setTimeZone:[NSTimeZone localTimeZone]];
    NSDate *newDate1 = [startDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]];
    NSDate *newDate2 = [endDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]];

    NSInteger startDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                            inUnit: NSEraCalendarUnit forDate:newDate1];
    NSInteger endDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit
                                          inUnit: NSEraCalendarUnit forDate:newDate2];
    return endDay-startDay;
}
4

2 に答える 2

5

タイム ゾーン オフセットが機能しない場合は、代わりに手動で加算または減算してみてはどうでしょうか。

あなたの場合NSDate *newDate = [oldDate dateByAddingTimeInterval:(-8 * 60 * 60)];は、+8 時間を差し引きます。

または、GMTオフセットも自動的に見つけたい場合は、次のようになりますNSDate *newDate = [oldDate dateByAddingTimeInterval:(-[[NSTimeZone localTimeZone] secondsFromGMT])

別の考え: おそらくより簡単な解決策は、時間情報を完全に無視することです。両方の日付に同じ任意の数値を設定するだけで、日付が同じタイムゾーンからのものである限り、GMT オフセットに関係なく、それらの間の真夜中の正しい数値が常に得られます。

于 2012-09-04T07:01:44.353 に答える
3

あなたが本当に欲しいのはNSDatemethodtimeIntervalSinceDate:であり、その結果を取り、それが 0 より大きく 86400 (1 日の秒数) より小さい場合、それは 1 日です。それ以外の場合は、結果を 86400 で割ると、日数が得られます。

現在のコードの方法では、2 日間の間に 2 時間しかないため、1 ではなく 0 の結果が表示されます。

編集 - そして真夜中が起こったかどうかを判断するために、頭のてっぺんに書いたこの関数を試してみましょう:

- (NSDate *) getMidnightDateFromDate: (NSDate *) originalDate
{
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSIntegerMax fromDate:originalDate];
    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];
    NSDate *midnight = [[NSCalendar currentCalendar] dateFromComponents:components];
    return(midnight);
}

- (BOOL) howManyDaysDifferenceBetween: startDate and: endDate
{
    NSDate * firstMidnight = [self getMidnightDateFromDate: startDate];
    NSDate * secondMidnight = [self getMidnightDateFromDate: endDate];
    NSTimeInterval timeBetween = [firstMidnight timeIntervalSinceDate: secondMidnight];

    NSInteger numberOfDays = (timeBetween / 86400);

    return(numberOfDays);
}

これは、この質問に対する Dave Delong の回答に基づいています。私のコードが動作するという保証はありません (私はテストしていません) が、コンセプトは正しいと思います。

于 2012-09-04T06:38:07.973 に答える