How can i calculate the number of days in a year for any calendar, not just gregorian. I have tried this
NSUInteger *days = [[NSCalendar currentCalendar] range
Another example in 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)
}
In 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);
}
Swift 3 extension:
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)
}
}
Maybe you can use the components:fromDate:toDate:options:
selector which is meant to (and I quote official Apple docs): Returns, as an NSDateComponents object using specified components, the difference between two supplied dates. ?
Also read this post that clarifies the behaviour you are seeing.
Wow, those are involved solutions. Just create a date of February 29 of the current year and see if it's converted to march first or not.
-(BOOL)isLeapYear {
NSDateComponents *components = [[NSDate currentCalendar] components:componentFlags fromDate:self];
components.month = 2;
components.day = 29;
NSDate *date = [[NSDate currentCalendar] dateFromComponents:components];
return (date.month == 2 && date.day == 29);
}
** Note, some of these items like date.month and date.day relay on other methods not shown, but you'll get the idea.
Here is the answer provided by William Clemens but in Objective 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
I don't know if anybody is still interested in this thread, but is another possible solution:
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];
using only 2 calls to NSCalendar
.