Objective-С: получение количества дней в календарном году
я использую следующее NSCalendar
метод для получения количества дней в календарном году:
NSRange range = [gregorian rangeOfUnit:NSDayCalendarUnit
inUnit:NSYearCalendarUnit
forDate:date];
Я жду range.length
возвращаемое значение типа NSRange
что 365 или 366 (дней).
однако этот код возвращает range.length
of 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 ответов
это вычисляет количество дней в году заданной даты:
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. Например, он возвращает 365 дней за 1500 год, хотя этот год был високосным в тогдашнем юлианском календаре. Григорианский календарь начинается 15 октября 1582 года. Вычисления, сделанные по григорианскому календарю, просто не определены до этой даты. Таким образом, реализация Apple верна. Я не знаю о правильной реализации в течение многих лет до 1583 года на какао.
вот относительно чистая версия. Это категория на 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];
}
спасибо AKV за указание на это -components:fromDate:toDate:options
будет работать в этом случае.
это, похоже, не работает для 1582 или до, что в ответе Николая Руэ, потому что расчеты григорианского календаря просто не определены до этого.
как насчет нахождения количества дней в данном году как: хотя это не относительное решение для вопроса.
-(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);
}
Edit:
как dateWithString: устарел, вы можете использовать
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter dateFormat]=@"dd-MM-yyyy";
NSDate *date=[dateFormatter dateFromString:dateString];
в форме date1
и date2
вы получаете количество дней в месяце даты.
вы можете использовать ту же функцию и просто пройти в сроки с февраля месяца. Если диапазон.длина возвращает 28, общее количество дней в году будет 365, если он возвращает 29, то количество дней будет 366.