How to calculate the age based on NSDate

32,513

Solution 1

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)!
}

Solution 2

Here's how you can calculate your actual age based on your birth date in years and days:

NSString *birthDate = @"03/31/1990";    
NSDate *todayDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/yyyy"];
int time = [todayDate timeIntervalSinceDate:[dateFormatter dateFromString:birthDate]];
int allDays = (((time/60)/60)/24);
int days = allDays%365;
int years = (allDays-days)/365;
NSLog(@"You live since %i years and %i days",years,days);

It returns the years and the exact days. And if you need you can change the NSDateFormatter and much more.

Solution 3

This is the code I got from this link.. it works great.. Out put will be like "5 years 6 months" and all usecases are covered in it.

- (NSString *)age:(NSDate *)dateOfBirth {
   NSInteger years;
   NSInteger months;
   NSInteger days;
   NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
   NSDateComponents *dateComponentsNow = [calendar components:unitFlags fromDate:[NSDate date]];
   NSDateComponents *dateComponentsBirth = [calendar components:unitFlags fromDate:dateOfBirth];
   if (([dateComponentsNow month] < [dateComponentsBirth month]) ||
(([dateComponentsNow month] == [dateComponentsBirth month]) && ([dateComponentsNow day] < [dateComponentsBirth day]))) {
   years = [dateComponentsNow year] - [dateComponentsBirth year] - 1;
} else {
   years = [dateComponentsNow year] - [dateComponentsBirth year];
}
if ([dateComponentsNow year] == [dateComponentsBirth year]) {
   months = [dateComponentsNow month] - [dateComponentsBirth month];
} else if ([dateComponentsNow year] > [dateComponentsBirth year] && [dateComponentsNow month] > [dateComponentsBirth month]) {
   months = [dateComponentsNow month] - [dateComponentsBirth month];
} else if ([dateComponentsNow year] > [dateComponentsBirth year] && [dateComponentsNow month] < [dateComponentsBirth month]) {
   months = [dateComponentsNow month] - [dateComponentsBirth month] + 12;
} else {
   months = [dateComponentsNow month] - [dateComponentsBirth month];
}
if ([dateComponentsNow year] == [dateComponentsBirth year] && [dateComponentsNow month] == [dateComponentsBirth month]) {
   days = [dateComponentsNow day] - [dateComponentsBirth day];
}
if (years == 0 && months == 0) {
   if (days == 1) {
      return [NSString stringWithFormat:@"%d day", days];
   } else {
      return [NSString stringWithFormat:@"%d days", days];
   }
} else if (years == 0) {
   if (months == 1) {
      return [NSString stringWithFormat:@"%d month", months];
   } else {
      return [NSString stringWithFormat:@"%d months", months];
   }
} else if ((years != 0) && (months == 0)) {
   if (years == 1) {
       return [NSString stringWithFormat:@"%d year", years];
   } else {
       return [NSString stringWithFormat:@"%d years", years];
   }
} else {
  if ((years == 1) && (months == 1)) {
      return [NSString stringWithFormat:@"%d year and %d month", years, months];
  } else if (years == 1) {
      return [NSString stringWithFormat:@"%d year and %d months", years, months];
  } else if (months == 1) {
      return [NSString stringWithFormat:@"%d years and %d month", years, months];
  } else {
      return [NSString stringWithFormat:@"%d years and %d months", years, months];
  }
}
}

If you want age as int try the following answer.. which I got from following link

- (NSInteger)age:(NSDate *)dateOfBirth {
  NSCalendar *calendar = [NSCalendar currentCalendar];
  unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
  NSDateComponents *dateComponentsNow = [calendar components:unitFlags fromDate:[NSDate date]];
  NSDateComponents *dateComponentsBirth = [calendar components:unitFlags fromDate:dateOfBirth];
  if (([dateComponentsNow month] < [dateComponentsBirth month]) ||
      (([dateComponentsNow month] == [dateComponentsBirth month]) && ([dateComponentsNow day] < [dateComponentsBirth day]))) {
    return [dateComponentsNow year] - [dateComponentsBirth year] - 1;
  } else {
    return [dateComponentsNow year] - [dateComponentsBirth year];
  }
}

Hope this helps some one..

Solution 4

A simple to use swift extension to get the age/how old is a NSDate

extension NSDate {
    var age: Int {
        let calendar: NSCalendar = NSCalendar.currentCalendar()
        let now = calendar.startOfDayForDate(NSDate())
        let birthdate = calendar.startOfDayForDate(self)
        let components = calendar.components(.Year, fromDate: birthdate, toDate: now, options: [])
        return components.year
    }
}

Exemple:

NSDate(timeIntervalSince1970:0).age // => 45 (as of nov 2015) Epoch happened 45 year ago !

By the way, you should be careful, this is the western conception of age, the counting is different in some other countries (Korea for exemple).

Solution 5

If u want to find age alone .use below one which include leap year calculation too

- (NSInteger)age:(NSDate *)dateOfBirth {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
    NSDateComponents *dateComponentsNow = [calendar components:unitFlags fromDate:[NSDate date]];
    NSDateComponents *dateComponentsBirth = [calendar components:unitFlags fromDate:dateOfBirth];
    if (([dateComponentsNow month] < [dateComponentsBirth month]) ||
        (([dateComponentsNow month] == [dateComponentsBirth month]) && ([dateComponentsNow day] < [dateComponentsBirth day]))) {
        return [dateComponentsNow year] - [dateComponentsBirth year] - 1;
    } else {
        return [dateComponentsNow year] - [dateComponentsBirth year];
    }
}
Share:
32,513
Linux world
Author by

Linux world

enered in to linux scripting ... working on SAN based...

Updated on July 09, 2022

Comments

  • Linux world
    Linux world 6 months

    how to calculate the age based on the birth date in this format 6/24/1976 mon/date/year...

  • Daniel Rinser
    Daniel Rinser over 10 years
    And there are no leap years where you live? ;)
  • Fabio Poloni
    Fabio Poloni over 10 years
    I live on Mars - Curiosity just hasn't discovered me yet. I'm not familiar with the possibilities of date-calculations in Objective-C, but my answer is a quite simple solution, but I think there's a more exact solution out there (on your planet) ;-)
  • Razvan about 10 years
    Wow ! Great answer ! This deserves a self Face Palm :D !
  • Francis F
    Francis F about 9 years
    That helped me to get the age as int. In my case I also had to convert the date from string before calling the function NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"MM/dd/yyyy"]; NSDate *dob = [dateFormat dateFromString:@"11/19/1986"]; NSLog(@"AGE:%d",[self age:dob]);
  • Francis F
    Francis F about 9 years
    That helped me to get the age as int. In my case I also had to convert the date from string before using this: NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"MM/dd/yyyy"]; NSDate *birthday = [dateFormat dateFromString:@"11/19/1986"];
  • Johnny
    Johnny almost 9 years
    what if it is a leap year?
  • Pedro over 8 years
    It's simpler, not accurate :-)
  • vishal dharankar
    vishal dharankar over 8 years
    most complete answer calculates months as well , thanks
  • cmario
    cmario about 7 years
    ofc I have to add this should be the correct answer
  • Yoko almost 7 years
    Great job, been using this ever since your answer! Thx!
  • Murray Sagal
    Murray Sagal over 6 years
    I made a bunch of test cases for this and ran into an edge case where a birthday of a year ago, for example, was returning zero. It seemed the time components were different enough to throw it off. I tried all the different option parameters but they didn't correct it. In the end I set now and birthday both to noon and that fixed it.
  • Luke Irvin
    Luke Irvin about 5 years
    How would you calculate months using this approach?
  • matt
    matt almost 3 years
    @MurraySagal This should be edited into the answer! It is crucial that now and birthday start at the same time, because of the quirk in the way we humans calculate age: it is your birthday all day no matter what time you were actually born at.