Objective c 目标C:获取日历年中的天数

Objective c 目标C:获取日历年中的天数,objective-c,cocoa-touch,cocoa,nsdate,nscalendar,Objective C,Cocoa Touch,Cocoa,Nsdate,Nscalendar,我使用以下NSCalendar方法获取日历年中的天数: NSRange range = [gregorian rangeOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:date]; 我希望range.length返回类型为NSRange的值,即365或366(天) 但是,对于日期值2005-06-

我使用以下
NSCalendar
方法获取日历年中的天数:

NSRange range = [gregorian rangeOfUnit:NSDayCalendarUnit 
                                inUnit:NSYearCalendarUnit 
                               forDate:date];
我希望
range.length
返回类型为
NSRange
的值,即365或366(天)

但是,对于日期值
2005-06-06
,此代码返回
范围.length
31

我的代码有什么问题

这是完整的代码片段:

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

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

您将获得约会月份的天数


您可以使用相同的函数,只需传入一个日期,将二月作为月份。如果range.length返回28,则一年中的总天数将为365天,如果返回29,则天数将为366天。

将给定年份中的天数计算为:尽管这不是问题的相对解决方案

-(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
,这里有一个相对干净的版本。这是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年或之前的情况不起作用,根据尼古拉·鲁厄的回答,这是因为公历计算在这之前没有定义。

这计算了给定日期一年中的天数:

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日开始。在公历上进行的计算在该日期之前没有定义。因此,苹果公司的实施是正确的。在1583年之前的几年里,我都不知道可可的正确使用方法。

他有31天,6月有30天。他在第6个月有30天,也就是6月(6月有30天)。我每个月(包括9月)都有31天。如果该方法总是返回下一个(更大的)日期类型(在本例中为月份),为什么我可以将
NSYearCalendarUnit
指定为
inUnit
参数?它在Xntrgk星球上也是无效的。像你这样的编码者要对y2k和可能的y10k错误负责!;)你每个月都会得到31分。是的,我在任何一年,任何一个月都会得到31分。一旦我改变了NSMonthCalenderUnit天数计数就正确了。!!!要么我们缺少一些东西,要么这个API有一些bug。这个方法工作正常。它在较大单位的时间跨度内计算单位的可能值范围。每年包含一个有31天的月。如果日期在不同的月份,则两个日期之间的
-days:andDate
的代码实际有效吗?是的,即使是在不同的年份。这是经过测试的,并且已经是我其他答案的一部分。。。几个月前,dateWithString:被弃用。出于好奇,Cocoa的公历实施是否也解释了各国逐渐采用日历的变幻莫测?例如,法国在收养方面落后意大利和西班牙两个月,而瑞典做了一些事情,比如跳过闰日一个世纪,而不是一次跳过一个星期。@Josh Caswell,据我所知,这甚至是没有模型的:你不能为特定的地区或日期要求日历。所以我想公历就是这样运作的。在定义闰年之前,你可以问它一个闰年,它的回答就像当时的公历一样。它是完全一致的:它使用“前公历”,大致意思是“使用相同的规则重新标记向后工作的天数”。因此,1500年不是闰年,而1200年是(与0000一起,请不要开始关于0年的辩论)。必须注意避免误解,但这是ISO 8601规定的,天文学家使用的,以及历史学家为了简化计算而转换成的(通常带有后缀“NS”)。@tc。谢谢你的澄清。伟大的信息提供!啊哈!那么ISO就是天主教徒新世界秩序图的一部分了!(笑话!)感谢Nikolai和@tc提供的信息。