如何计算任何日历的一年中的天数,而不仅仅是格里高利。 我试过这个
NSUInteger *days = [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];
但是这给了我当月的天数而不是当年的天数。
答案 0 :(得分:10)
我终于想出了一个有效的解决方案。我所做的是先计算一年中的月数,然后计算每个月的天数。
代码如下所示:
NSUInteger days = 0;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *today = [NSDate date];
NSDateComponents *components = [calendar components:NSYearCalendarUnit fromDate:today];
NSUInteger months = [calendar rangeOfUnit:NSMonthCalendarUnit
inUnit:NSYearCalendarUnit
forDate:today].length;
for (int i = 1; i <= months; i++) {
components.month = i;
NSDate *month = [calendar dateFromComponents:components];
days += [calendar rangeOfUnit:NSDayCalendarUnit
inUnit:NSMonthCalendarUnit
forDate:month].length;
}
return days;
它并不像我希望的那样整洁,但它适用于任何日历,例如普通的格里高利或伊斯兰日历。
答案 1 :(得分:8)
一般情况下,您可以使用一年中的第一天和下一年的第一天之间的天数。这是说明这种方法的代码
- (NSDate *)firstDateOfYear:(NSInteger)year
{
NSDateComponents *dc = [[NSDateComponents alloc] init];
dc.year = year;
dc.month = 1;
dc.day = 1;
return [[NSCalendar currentCalendar] dateFromComponents:dc];
}
- (NSUInteger)numberOfDaysInYear:(NSInteger)year
{
NSDate *firstDateOfYear = [self firstDateOfYear:year];
NSDate *firstDateOfNextYear = [self firstDateOfYear:year + 1];
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit fromDate:firstDateOfYear toDate:firstDateOfNextYear options:0];
return [components day];
}
答案 2 :(得分:3)
我不知道objective-c但它是一个简单的算法来确定它是否是闰年。
if ( year % 400 == 0 )
then 366 // Leap Year
else if ( year % 100 == 0 )
then 365 // Non-Leap Year
else if ( year % 4 == 0 )
then 366 // Leap Year
else
365 // Non-Leap Year
或者,如果你想要一个不那么冗长的版本
if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))
then 366 // Leap Year
else
365 // Non-Leap Year
答案 3 :(得分:2)
我不知道是否还有人对此主题感兴趣,但这是另一种可能的解决方案:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *startOfYear;
NSTimeInterval lengthOfYear;
[calendar rangeOfUnit:NSYearCalendarUnit
startDate:&startOfYear
interval:&lengthOfYear
forDate:[NSDate date]];
NSDate *endOfYear = [startOfYear dateByAddingTimeInterval:lengthOfYear];
NSDateComponents *comp = [calendar components:NSDayCalendarUnit
fromDate:startOfYear
toDate:endOfYear
options:0];
NSUInteger numberOfDaysInThisYear = [comp day];
仅使用NSCalendar
进行2次调用。
答案 4 :(得分:1)
也许您可以使用components:fromDate:toDate:options:
选择器(我引用official Apple docs):使用指定组件作为NSDateComponents对象返回两个提供日期之间的差异。< / em>?
另请阅读this post,澄清您所看到的行为。
答案 5 :(得分:1)
为了做你想做的事,你必须找到特定日历的一个月和一年中的天数。对于使用日/月/年单位(或具有一些等效映射)的任何日历,此函数将执行您所需的功能:
NSInteger getDaysInYear(NSDate* date)
{
// Get the current calendar
NSCalendar* c = [NSCalendar currentCalendar];
// Find the range for days and months in this calendar
NSRange dayRange = [c rangeOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:date];
NSRange monthRange = [c rangeOfUnit:NSMonthCalendarUnit inUnit:NSYearCalendarUnit forDate:date];
// Get the year from the suppled date
NSDateComponents* yearComps = [c components:NSYearCalendarUnit fromDate:date];
NSInteger thisYear = [yearComps year];
// Create the first day of the year in the current calendar
NSUInteger firstDay = dayRange.location;
NSUInteger firstMonth = monthRange.location;
NSDateComponents* firstDayComps = [[[NSDateComponents alloc] init] autorelease];
[firstDayComps setDay:firstDay];
[firstDayComps setMonth:firstMonth];
[firstDayComps setYear:thisYear];
NSDate* firstDayDate = [c dateFromComponents:firstDayComps];
// Create the last day of the year in the current calendar
NSUInteger lastDay = dayRange.length;
NSUInteger lastMonth = monthRange.length;
NSDateComponents* lastDayComps = [[[NSDateComponents alloc] init] autorelease];
[lastDayComps setDay:lastDay];
[lastDayComps setMonth:lastMonth];
[lastDayComps setYear:thisYear];
NSDate* lastDayDate = [c dateFromComponents:lastDayComps];
// Find the difference in days between the first and last days of the year
NSDateComponents* diffComps = [c components:NSDayCalendarUnit
fromDate:firstDayDate
toDate:lastDayDate
options:0];
// We have to add one since this was subtraction but we really want to
// give the total days in the year
return [diffComps day] + 1;
}
如果您想指定今年,可以将其简称为getDaysInYear([NSDate date]);
,或者您可以创建特定年份/其他组件的日期并传递该日期。您也可以非常轻松地将其重新实现为方法调用。
答案 6 :(得分:1)
使用SWIFT 5.3和Xcode 12找到了解决此问题的最佳解决方案。
将其放入操场,调用checkLeapYear函数,将其传递一年,然后进行游戏。
func checkLeapYear(year: Int) {
if year % 4 == 0{
if year % 100 == 0 {
if year % 400 == 0{
print("\(year) is a Leap Year!")
} else {
print("\(year) is NOT a Leap Year!")
}
} else {
print("\(year) is a Leap Year!")
}
} else {
print("\(year) is NOT a Leap Year!")
}
}
该算法非常棘手,因此我建议您在自己执行该算法时使用以下逻辑:
答案 7 :(得分:0)
2
**注意,其中一些项目如date.month和date.day继电器未显示其他方法,但您可以理解。
答案 8 :(得分:0)
Swift 3中的另一个例子:
let calendar = Calendar.current
let date = Date() // use any date in this year
if let yearInterval = calendar.dateInterval(of: Calendar.Component.year, for: date),
let daysInYear = calendar.dateComponents([Calendar.Component.day], from: yearInterval.start, to: yearInterval.end).day
{
print(daysInYear)
}
在Objective-C中:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate* date = [NSDate date];
NSDate* startOfYear = nil;
NSTimeInterval yearDuration = 0;
if ([calendar rangeOfUnit:NSCalendarUnitYear startDate:&startOfYear interval:&yearDuration forDate:d
]) {
NSDateComponents *daysComponents = [calendar components:NSCalendarUnitDay fromDate:startOfYear toDate:[startOfYear dateByAddingTimeInterval:yearDuration] options:0];
NSInteger daysInYear = daysComponents.day;
NSLog(@"Days in year: %ld", daysInYear);
}
答案 9 :(得分:0)
Swift 3扩展名:
extension Date {
public func isLeapYear() -> Bool {
let components = Calendar.current.dateComponents([.year], from: self)
guard let year = components.year else { return false }
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
}
}
答案 10 :(得分:-1)
以下是William Clemens提供的答案,但目标C:
int year;
int yearCode;
if ( year % 400 == 0 )
{yearCode = 366;} // Leap Year
else if ( year % 100 == 0 )
{
{yearCode = 365;} // Non Leap Year
}
else if ( year % 4 == 0 )
{
{yearCode = 366;} // Leap Year
}
else
{yearCode = 365;} // Non-Leap Year
答案 11 :(得分:-2)
[[NSCalendar currentCalendar] ordinalityOfUnit:NSYearCalendarUnit
inUnit:NSEraCalendarUnit forDate:date];