如何计算目标C中今年的天数

时间:2010-01-16 18:05:36

标签: iphone objective-c

如何计算任何日历的一年中的天数,而不仅仅是格里高利。 我试过这个

NSUInteger *days = [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];

但是这给了我当月的天数而不是当年的天数。

12 个答案:

答案 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!")
    }
}

该算法非常棘手,因此我建议您在自己执行该算法时使用以下逻辑:

  1. 如果年份可以被4整除,请转到步骤2。 否则,请转到步骤5。
  2. 如果年份可以被100整除,请转到步骤3。 否则,请转到步骤4。
  3. 如果年份可以被400整除,请转到步骤4。 否则,请转到步骤5。
  4. 这一年是a年。
  5. 这不是a年。

答案 7 :(得分:0)

哇,那些涉及的解决方案。只需创建当年2月29日的日期,看看它是否首先转换为游行。

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];