Many of these answers don't properly account for leap years and such, best is to use Apple's methods instead of dividing by constants.
Swift
let birthday: NSDate = ...
let now = Date()
let ageComponents = calendar.dateComponents([.year], from: birthday, to: now)
let age = ageComponents.year
Objective-C
NSDate* birthday = ...;
NSDate* now = [NSDate date];
NSDateComponents* ageComponents = [[NSCalendar currentCalendar]
components:NSCalendarUnitYear
fromDate:birthday
toDate:now
options:0];
NSInteger age = [ageComponents year];
I think this is cleaner and more accurate than any of the other answers here.
Edit
Increase accuracy by setting both birthday
and now
to noon. Here is one way to do that with a Date
extension (in Swift)...
/// Returns a new date identical to the receiver except set to precisely noon.
/// Example: let now = Date().atNoon()
func atNoon() -> Date {
var components = (Calendar.current as NSCalendar).components([.day, .month, .year, .era, .calendar, .timeZone], from: self)
components.hour = 12
components.minute = 0
components.second = 0
components.nanosecond = 0
return Calendar.current.date(from: components)!
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…