8

次のNSCalendarメソッドを使用して、暦年の日数を取得しています。

NSRange range = [gregorian rangeOfUnit:NSDayCalendarUnit 
                                inUnit:NSYearCalendarUnit 
                               forDate:date];

365 または 366 (日)range.lengthの型の戻り値を期待しています。NSRange

range.lengthただし、このコードはの31日付値に対して を返します2005-06-06

コードの何が問題になっていますか?

これは完全なコード スニペットです。

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

[subArray enumerateObjectsUsingBlock:
   ^(NSDate *date, NSUInteger idx, BOOL *stop) {
   NSUInteger numberOfDays = [gregorian ordinalityOfUnit:NSDayCalendarUnit
   inUnit:NSYearCalendarUnit forDate:date];
}];
4

4 に答える 4

2

これは、指定された日付の 1 年の日数を計算します。

NSDate *someDate = [NSDate date];

NSDate *beginningOfYear;
NSTimeInterval lengthOfYear;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian rangeOfUnit:NSYearCalendarUnit
             startDate:&beginningOfYear
              interval:&lengthOfYear
               forDate:someDate];
NSDate *nextYear = [beginningOfYear dateByAddingTimeInterval:lengthOfYear];
NSInteger startDay = [gregorian ordinalityOfUnit:NSDayCalendarUnit
                                          inUnit:NSEraCalendarUnit
                                         forDate:beginningOfYear];
NSInteger endDay = [gregorian ordinalityOfUnit:NSDayCalendarUnit
                                        inUnit:NSEraCalendarUnit
                                       forDate:nextYear];
NSInteger daysInYear = endDay - startDay;

悲しい警告: これは 1582 年には正しく機能しません。

グレゴールが現在広く使用されている暦を導入した 1582 年には、太陽暦と暦年を一致させるための修正が必要でした。そこで、彼らは現実的な解決策を採用しました。10 月 5 日から 14 日までの期間を終了したのです。(彼らも平日を変えるほどクレイジーではありませんでした)。その結果、1582 年は 355 日しかありません。

補遺:上記のコードは、1582 年以降の年に対してのみ正しく機能します。たとえば、当時使用されていたユリウス暦では今年がうるう年であったとしても、1500 年に対して 365 日を返します。グレゴリオ暦は 1582 年 10 月 15 日に始まります。グレゴリオ暦で行われた計算は、その日付より前には定義されていません。このように、Apple の実装は正しいです。1583 年より前の Cocoa での正しい実装については知りません。

于 2013-02-18T18:00:01.417 に答える
1

これは比較的クリーンなバージョンです。NSCalendarのカテゴリです。

- (NSInteger) daysInYear:(NSInteger) year {
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.year = year;
    dateComponents.month = dateComponents.day = 1;
    NSDate *firstOfYear = [self dateFromComponents:dateComponents];
    dateComponents.year = year + 1;
    NSDate *firstOfFollowingYear = [self dateFromComponents:dateComponents];

    return [[self components:NSDayCalendarUnit
                   fromDate:firstOfYear
                     toDate:firstOfFollowingYear
                     options:0] day];    
}

-components:fromDate:toDate:optionsこの場合に機能することを指摘してくれたAKVに感謝します。

これは1582以前では機能しないようです。これは、ニコライルーエの答えによると、グレゴリオ暦の計算がそれ以前に定義されていないためです。

于 2013-02-18T17:57:05.003 に答える
1

特定の年の日数を次のように見つけることはどうですか:これは質問の相対的な解決策ではありませんが。

-(NSInteger)daysBetweenTwoDates:(NSDate *)fromDateTime andDate:(NSDate *)toDateTime{

    NSDate *fromDate;
    NSDate *toDate;

    NSCalendar *calendar = [NSCalendar currentCalendar];

    [calendar rangeOfUnit:NSDayCalendarUnit startDate:&fromDate interval:NULL forDate:fromDateTime];
    [calendar rangeOfUnit:NSDayCalendarUnit startDate:&toDate interval:NULL forDate:toDateTime];

    NSDateComponents *difference = [calendar components:NSDayCalendarUnit fromDate:fromDate toDate:toDate options:0];

    return [difference day]; 
}

-(void)someMethod {

    NSString *yourYear=@"2012";

    NSDate *date1 = [NSDate dateWithString:[NSString stringWithFormat:@"%@-01-01 00:00:00 +0000",yourYear]];
    NSDate *date2 = [NSDate dateWithString:[NSString stringWithFormat:@"%@-12-31 00:00:00 +0000",yourYear]];

    NSInteger numberOfDays=[self daysBetweenTwoDates:date1 andDate:date2];    

    NSLog(@"There are %ld days in between the two dates.", numberOfDays);
}            

編集:

dateWithString: は非推奨であるため、使用できます

NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter dateFormat]=@"dd-MM-yyyy";
NSDate *date=[dateFormatter dateFromString:dateString];

形成date1し、date2

于 2013-02-18T17:32:13.633 に答える
0

あなたはあなたの日付の月の日数を取得しています。

同じ関数を使用して、2月を月とする日付を渡すことができます。range.lengthが28を返す場合、その年の合計日数は365になり、29を返す場合、日数は366になります。

于 2013-02-18T16:44:43.537 に答える