153

I want to return an age in years as an int in a Java method. What I have now is the following where getBirthDate() returns a Date object (with the birth date ;-)):

public int getAge() {
    long ageInMillis = new Date().getTime() - getBirthDate().getTime();

    Date age = new Date(ageInMillis);

    return age.getYear();
}

But since getYear() is deprecated I'm wondering if there is a better way to do this? I'm not even sure this works correctly, since I have no unit tests in place (yet).

Chris Farmer
  • 23,314
  • 32
  • 110
  • 161
nojevive
  • 3,238
  • 3
  • 20
  • 18
  • Changed my mind about that: the other question only has an approximation of years between dates, not a truly correct age. – cletus Jul 12 '09 at 14:48
  • Given that he's returning an int, can you clarify what you mean by a 'correct' age ? – Brian Agnew Jul 12 '09 at 15:02
  • 2
    Date vs Calendar is a fundamental concept that can be gleaned from reading the Java documentation. I cannot understand why this would be upvoted so much. – demongolem Jul 03 '12 at 22:14
  • @demongolem ??? Date & Calendar are easily understood?! No, not at all. There are a zillion Questions on the subject here on Stack Overflow. The Joda-Time project produced one of the most popular libraries, to substitute for those troublesome date-time classes. Later, Sun, Oracle, and the JCP community accepted [JSR 310](https://jcp.org/en/jsr/detail?id=310) (*java.time*), admitting that the legacy classes were hopelessly inadequate. For more info, see [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Feb 28 '18 at 22:21

28 Answers28

175

JDK 8 makes this easy and elegant:

public class AgeCalculator {

    public static int calculateAge(LocalDate birthDate, LocalDate currentDate) {
        if ((birthDate != null) && (currentDate != null)) {
            return Period.between(birthDate, currentDate).getYears();
        } else {
            return 0;
        }
    }
}

A JUnit test to demonstrate its use:

public class AgeCalculatorTest {

    @Test
    public void testCalculateAge_Success() {
        // setup
        LocalDate birthDate = LocalDate.of(1961, 5, 17);
        // exercise
        int actual = AgeCalculator.calculateAge(birthDate, LocalDate.of(2016, 7, 12));
        // assert
        Assert.assertEquals(55, actual);
    }
}

Everyone should be using JDK 8 by now. All earlier versions have passed the end of their support lives.

duffymo
  • 293,097
  • 41
  • 348
  • 541
  • 10
    The DAY_OF_YEAR comparison can lead to erroneous result when dealing with leap years. – sinuhepop Apr 18 '12 at 18:03
  • 1
    The variable dateOfBirth has to be Date object. How can I create a Date object with the birth date? – Erick Sep 02 '15 at 21:25
  • In view of the fact that we are 9 years on, and in case Java 8 is used, this should be the solution to be used. – nojevive Apr 10 '18 at 14:48
  • JDK 9 is the current production version. More true than ever. – duffymo Apr 10 '18 at 15:23
  • I would rather not `return 0` but use `Integer` and `null` to be consistent with _nullability_ of the parameters. – Steve Oh Sep 06 '18 at 06:33
  • FYI, some people pay for extended support contracts to continue using old versions of Java beyond the *public* End-Of-Life date you mentioned. – Basil Bourque Jan 11 '19 at 18:04
  • Why would you want to? Are you still running Windows XP, too? There's a certain degree of currency that's necessary. Security patches aren't available for older versions. – duffymo Jan 11 '19 at 18:15
  • 2
    @SteveOh I disagree. I would rather not accept `null`s at all, but instead use `Objects.requireNonNull`. – MC Emperor Apr 09 '19 at 09:55
  • In case anyone else needs to convert their Date into LocalDate like @Erick: https://stackoverflow.com/questions/21242110/convert-java-util-date-to-java-time-localdate – Sander Oct 18 '19 at 10:29
  • how about the older JDK instead of JDK 8? – gumuruh May 28 '20 at 16:56
  • Nobody should be using a JDK older than 8. I recommend. 11 or 13. – duffymo May 28 '20 at 19:32
173

Check out Joda, which simplifies date/time calculations (Joda is also the basis of the new standard Java date/time apis, so you'll be learning a soon-to-be-standard API).

EDIT: Java 8 has something very similar and is worth checking out.

e.g.

LocalDate birthdate = new LocalDate (1970, 1, 20);
LocalDate now = new LocalDate();
Years age = Years.yearsBetween(birthdate, now);

which is as simple as you could want. The pre-Java 8 stuff is (as you've identified) somewhat unintuitive.

Brian Agnew
  • 254,044
  • 36
  • 316
  • 423
  • 2
    @HoàngLong: From the JavaDocs: "This class does not represent a day, but the millisecond instant at midnight. If you need a class that represents the whole day, then an Interval or a LocalDate may be more suitable." We really *do* want to represent a date here. – Jon Skeet Mar 08 '12 at 06:24
  • If you want to do it the way @JohnSkeet suggests, it's like this: Years age = Years.yearsBetween(new LocalDate(getBirthDate()), new LocalDate()); – Fletch Sep 24 '12 at 15:41
  • Don't know *why* I used DateMidnight, and I note now it's deprecated. Now changed to use LocalDate – Brian Agnew Nov 06 '13 at 15:22
  • it works, but why is adding a 'P' and 'Y' to the age ? i.e. it prints "P45Y" ? – Bor Apr 18 '15 at 08:05
  • 2
    @Bor - http://joda-time.sourceforge.net/apidocs/org/joda/time/Years.html#toString%28%29 – Brian Agnew Apr 19 '15 at 15:43
  • 2
    @IgorGanapolsky Indeed the main difference is: Joda-Time use constructors while Java-8 and ThreetenBP use static factory methods. For a subtle bug in the way Joda-Time calculates age, please look at [my answer](http://stackoverflow.com/a/27738766/2491410) where I have given an overview about the behaviour of different libraries. – Meno Hochschild Aug 20 '15 at 09:08
  • The Class introduced in Java 8 has the name `Year` not `Years`... edit queue is full... – kiltek May 18 '17 at 08:31
  • can't found Year identification? – gumuruh May 28 '20 at 16:57
44

Modern answer and overview

a) Java-8 (java.time-package)

LocalDate start = LocalDate.of(1996, 2, 29);
LocalDate end = LocalDate.of(2014, 2, 28); // use for age-calculation: LocalDate.now()
long years = ChronoUnit.YEARS.between(start, end);
System.out.println(years); // 17

Note that the expression LocalDate.now() is implicitly related to the system timezone (which is often overlooked by users). For clarity it is generally better to use the overloaded method now(ZoneId.of("Europe/Paris")) specifying an explicit timezone (here "Europe/Paris" as example). If the system timezone is requested then my personal preference is to write LocalDate.now(ZoneId.systemDefault()) to make the relation to the system timezone clearer. This is more writing effort but makes reading easier.

b) Joda-Time

Please note that the proposed and accepted Joda-Time-solution yields a different computation result for the dates shown above (a rare case), namely:

LocalDate birthdate = new LocalDate(1996, 2, 29);
LocalDate now = new LocalDate(2014, 2, 28); // test, in real world without args
Years age = Years.yearsBetween(birthdate, now);
System.out.println(age.getYears()); // 18

I consider this as a small bug but the Joda-team has a different view on this weird behaviour and does not want to fix it (weird because the day-of-month of end date is smaller than of start date so the year should be one less). See also this closed issue.

c) java.util.Calendar etc.

For comparison see the various other answers. I would not recommend using these outdated classes at all because the resulting code is still errorprone in some exotic cases and/or way too complex considering the fact that the original question sounds so simple. In year 2015 we have really better libraries.

d) About Date4J:

The proposed solution is simple but will sometimes fail in case of leap years. Just evaluating the day of year is not reliable.

e) My own library Time4J:

This works similar to Java-8-solution. Just replace LocalDate by PlainDate and ChronoUnit.YEARS by CalendarUnit.YEARS. However, getting "today" requires an explicit timezone reference.

PlainDate start = PlainDate.of(1996, 2, 29);
PlainDate end = PlainDate.of(2014, 2, 28);
// use for age-calculation (today): 
// => end = SystemClock.inZonalView(EUROPE.PARIS).today();
// or in system timezone: end = SystemClock.inLocalView().today();
long years = CalendarUnit.YEARS.between(start, end);
System.out.println(years); // 17
Meno Hochschild
  • 38,305
  • 7
  • 88
  • 115
  • 1
    Thank you for the Java 8 version! Saved me some time :) Now I just have to figure out how to extract remainding months. E.g. 1 year and 1 month. :) – thomas77 Feb 12 '15 at 09:04
  • 2
    @thomas77 Thanks for reply, combined years and months (and maybe days) can be done using `java.time.Period' in Java-8. If you also want to take into account other units like hours then Java-8 does not offer a solution. – Meno Hochschild Feb 12 '15 at 09:22
  • Thank you again (and for the quick response) :) – thomas77 Feb 12 '15 at 10:00
  • 1
    I suggest **specifying a time zone** when using `LocalDate.now`. If omitted the JVM’s current default time zone is implicitly applied. That default can change between machines/OSes/settings, and also can at any moment *during runtime* by any code calling [`setDefault`](http://docs.oracle.com/javase/8/docs/api/java/util/TimeZone.html#setDefault-java.util.TimeZone-). I recommend being specific, such as `LocalDate.now( ZoneId.for( "America/Montreal" ) )` – Basil Bourque Aug 20 '15 at 05:39
  • @BasilBourque I have adjusted my answer related to Java-8 to incorporate your comment and to advise users to be as much specific as possible. – Meno Hochschild Aug 20 '15 at 08:59
  • old Android versions doesn't support Java 8 – Martin Jun 09 '18 at 10:13
  • 1
    @GoCrafter_LP Yes, you can apply ThreetenABP simulating Java-8, or Joda-Time-Android (from D. Lew) or my lib Time4A for such older Android versions. – Meno Hochschild Jun 09 '18 at 17:22
43
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(...);
if (dob.after(now)) {
  throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
int age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
  age--;
} else if (month1 == month2) {
  int day1 = now.get(Calendar.DAY_OF_MONTH);
  int day2 = dob.get(Calendar.DAY_OF_MONTH);
  if (day2 > day1) {
    age--;
  }
}
// age is now correct
cletus
  • 578,732
  • 155
  • 890
  • 933
  • Yeah, the calendar class is terrible. Unfortunately, at work sometimes I have to use it :/. Thanks Cletus for posting this – Steve Sep 30 '16 at 18:49
  • 1
    Replace Calendar.MONTH and Calendar.DAY_OF_MONTH with Calendar.DAY_OF_YEAR and it will at least be a bit cleaner – Tobbbe May 30 '17 at 08:13
  • @Tobbbe If you are born on 1st March in a leap year, then your birthday is on 1st March in the following year, not 2nd. DAY_OF_YEAR won't work. – Airsource Ltd Feb 27 '20 at 14:43
19
/**
 * This Method is unit tested properly for very different cases , 
 * taking care of Leap Year days difference in a year, 
 * and date cases month and Year boundary cases (12/31/1980, 01/01/1980 etc)
**/

public static int getAge(Date dateOfBirth) {

    Calendar today = Calendar.getInstance();
    Calendar birthDate = Calendar.getInstance();

    int age = 0;

    birthDate.setTime(dateOfBirth);
    if (birthDate.after(today)) {
        throw new IllegalArgumentException("Can't be born in the future");
    }

    age = today.get(Calendar.YEAR) - birthDate.get(Calendar.YEAR);

    // If birth date is greater than todays date (after 2 days adjustment of leap year) then decrement age one year   
    if ( (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3) ||
            (birthDate.get(Calendar.MONTH) > today.get(Calendar.MONTH ))){
        age--;

     // If birth date and todays date are of same month and birth day of month is greater than todays day of month then decrement age
    }else if ((birthDate.get(Calendar.MONTH) == today.get(Calendar.MONTH )) &&
              (birthDate.get(Calendar.DAY_OF_MONTH) > today.get(Calendar.DAY_OF_MONTH ))){
        age--;
    }

    return age;
}
Dyppl
  • 11,217
  • 8
  • 42
  • 67
Farhan Munir
  • 191
  • 1
  • 4
  • 2
    What is the purpose of the check `(birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)`? It seems pointless with the existence of the month and dayofmonth comparisons. – Jed Schaaf Mar 03 '16 at 03:14
14

I simply use the milliseconds in a year constant value to my advantage:

Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);
Lou Morda
  • 4,693
  • 2
  • 40
  • 47
13

If you are using GWT you will be limited to using java.util.Date, here is a method that takes the date as integers, but still uses java.util.Date:

public int getAge(int year, int month, int day) {
    Date now = new Date();
    int nowMonth = now.getMonth()+1;
    int nowYear = now.getYear()+1900;
    int result = nowYear - year;

    if (month > nowMonth) {
        result--;
    }
    else if (month == nowMonth) {
        int nowDay = now.getDate();

        if (day > nowDay) {
            result--;
        }
    }
    return result;
}
Craigo
  • 2,630
  • 22
  • 18
7

It's perhaps surprising to note that you don't need to know how many days or months there are in a year or how many days are in those months, likewise, you don't need to know about leap years, leap seconds, or any of that stuff using this simple, 100% accurate method:

public static int age(Date birthday, Date date) {
    DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
    int d1 = Integer.parseInt(formatter.format(birthday));
    int d2 = Integer.parseInt(formatter.format(date));
    int age = (d2-d1)/10000;
    return age;
}
weston
  • 51,132
  • 20
  • 132
  • 192
  • 1
    I'm looking for solution for java 6 and 5. This is simple yet accurate. – Jj Tuibeo May 13 '20 at 06:52
  • For NullPointerException safety please add, `if (birthday != null && date != null)`, and return default value 0. – stefan-dan Mar 17 '21 at 07:16
  • I would rather it crashed than have a default age of 0 and moving on to cause a bug elsewhere. Imagine: if I asked you "I was born on ___ and today is Mar-17-2021, how old am I?" you would say "I can't answer that", not "you are 0" – weston Mar 17 '21 at 17:16
5

The correct answer using JodaTime is:

public int getAge() {
    Years years = Years.yearsBetween(new LocalDate(getBirthDate()), new LocalDate());
    return years.getYears();
}

You could even shorten it into one line if you like. I copied the idea from BrianAgnew's answer, but I believe this is more correct as you see from the comments there (and it answers the question exactly).

Community
  • 1
  • 1
Fletch
  • 4,061
  • 2
  • 34
  • 48
5

This is an improved version of the one above... considering that you want age to be an 'int'. because sometimes you don't want to fill your program with a bunch of libraries.

public int getAge(Date dateOfBirth) {
    int age = 0;
    Calendar born = Calendar.getInstance();
    Calendar now = Calendar.getInstance();
    if(dateOfBirth!= null) {
        now.setTime(new Date());
        born.setTime(dateOfBirth);  
        if(born.after(now)) {
            throw new IllegalArgumentException("Can't be born in the future");
        }
        age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);             
        if(now.get(Calendar.DAY_OF_YEAR) < born.get(Calendar.DAY_OF_YEAR))  {
            age-=1;
        }
    }  
    return age;
}
cass
  • 1,046
  • 12
  • 13
4

With the date4j library :

int age = today.getYear() - birthdate.getYear();
if(today.getDayOfYear() < birthdate.getDayOfYear()){
  age = age - 1; 
}
John O
  • 1,585
  • 11
  • 21
3

I use this piece of code for age calculation ,Hope this helps ..no libraries used

private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());

public static int calculateAge(String date) {

    int age = 0;
    try {
        Date date1 = dateFormat.parse(date);
        Calendar now = Calendar.getInstance();
        Calendar dob = Calendar.getInstance();
        dob.setTime(date1);
        if (dob.after(now)) {
            throw new IllegalArgumentException("Can't be born in the future");
        }
        int year1 = now.get(Calendar.YEAR);
        int year2 = dob.get(Calendar.YEAR);
        age = year1 - year2;
        int month1 = now.get(Calendar.MONTH);
        int month2 = dob.get(Calendar.MONTH);
        if (month2 > month1) {
            age--;
        } else if (month1 == month2) {
            int day1 = now.get(Calendar.DAY_OF_MONTH);
            int day2 = dob.get(Calendar.DAY_OF_MONTH);
            if (day2 > day1) {
                age--;
            }
        }
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return age ;
}
Ameen Maheen
  • 2,427
  • 1
  • 24
  • 28
3

Try to copy this one in your code, then use the method to get the age.

public static int getAge(Date birthday)
{
    GregorianCalendar today = new GregorianCalendar();
    GregorianCalendar bday = new GregorianCalendar();
    GregorianCalendar bdayThisYear = new GregorianCalendar();

    bday.setTime(birthday);
    bdayThisYear.setTime(birthday);
    bdayThisYear.set(Calendar.YEAR, today.get(Calendar.YEAR));

    int age = today.get(Calendar.YEAR) - bday.get(Calendar.YEAR);

    if(today.getTimeInMillis() < bdayThisYear.getTimeInMillis())
        age--;

    return age;
}
Kevin
  • 452
  • 6
  • 13
2

The fields birth and effect are both date fields:

Calendar bir = Calendar.getInstance();
bir.setTime(birth);
int birthNm = bir.get(Calendar.DAY_OF_YEAR);
int birthYear = bir.get(Calendar.YEAR);
Calendar eff = Calendar.getInstance();
eff.setTime(effect);

This basically a modification of John O's solution without using depreciated methods. I spent a fair amount of time trying to get his code to work in in my code. Maybe this will save others that time.

John B
  • 21
  • 1
1

What about this one?

public Integer calculateAge(Date date) {
    if (date == null) {
        return null;
    }
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date);
    Calendar cal2 = Calendar.getInstance();
    int i = 0;
    while (cal1.before(cal2)) {
        cal1.add(Calendar.YEAR, 1);
        i += 1;
    }
    return i;
}
Andre P.
  • 27
  • 1
  • This is a really cute suggestion (when you aren't using Joda and can't use Java 8) however the algorithm is slightly wrong because you're 0 until the whole of the first year passes. So you need to add a year to the date before you start the while loop. – Dagmar Jan 18 '18 at 12:10
1

String dateofbirth has the date of birth. and format is whatever (defined in the following line):

org.joda.time.format.DateTimeFormatter formatter =  org.joda.time.format.DateTimeFormat.forPattern("mm/dd/yyyy");

Here is how to format:

org.joda.time.DateTime birthdateDate = formatter.parseDateTime(dateofbirth );
org.joda.time.DateMidnight birthdate = new         org.joda.time.DateMidnight(birthdateDate.getYear(), birthdateDate.getMonthOfYear(), birthdateDate.getDayOfMonth() );
org.joda.time.DateTime now = new org.joda.time.DateTime();
org.joda.time.Years age = org.joda.time.Years.yearsBetween(birthdate, now);
java.lang.String ageStr = java.lang.String.valueOf (age.getYears());

Variable ageStr will have the years.

JoshDM
  • 4,838
  • 7
  • 42
  • 70
1

Elegant, seemingly correct, timestamp difference based variant of Yaron Ronen solution.

I am including a unit test to prove when and why it is not correct. It is impossible due (to possibly) different number of leap days (and seconds) in any timestamp difference. The discrepancy should be max +-1 day (and one second) for this algorithm, see test2(), whereas Yaron Ronen solution based on completely constant assumption of timeDiff / MILLI_SECONDS_YEAR can differ 10 days for a 40ty year old, nevertheless this variant is incorrect too.

It is tricky, because this improved variant, using formula diffAsCalendar.get(Calendar.YEAR) - 1970, returns correct results most of the time, as number of leap years in on average same between two dates.

/**
 * Compute person's age based on timestamp difference between birth date and given date
 * and prove it is INCORRECT approach.
 */
public class AgeUsingTimestamps {

public int getAge(Date today, Date dateOfBirth) {
    long diffAsLong = today.getTime() - dateOfBirth.getTime();
    Calendar diffAsCalendar = Calendar.getInstance();
    diffAsCalendar.setTimeInMillis(diffAsLong);
    return diffAsCalendar.get(Calendar.YEAR) - 1970; // base time where timestamp=0, precisely 1/1/1970 00:00:00 
}

    final static DateFormat df = new SimpleDateFormat("dd.MM.yyy HH:mm:ss");

    @Test
    public void test1() throws Exception {
        Date dateOfBirth = df.parse("10.1.2000 00:00:00");
        assertEquals(87, getAge(df.parse("08.1.2088 23:59:59"), dateOfBirth));
        assertEquals(87, getAge(df.parse("09.1.2088 23:59:59"), dateOfBirth));
        assertEquals(88, getAge(df.parse("10.1.2088 00:00:01"), dateOfBirth));
    }

    @Test
    public void test2() throws Exception {
        // between 2000 and 2021 was 6 leap days
        // but between 1970 (base time) and 1991 there was only 5 leap days
        // therefore age is switched one day earlier
            // See http://www.onlineconversion.com/leapyear.htm
        Date dateOfBirth = df.parse("10.1.2000 00:00:00");
        assertEquals(20, getAge(df.parse("08.1.2021 23:59:59"), dateOfBirth));
        assertEquals(20, getAge(df.parse("09.1.2021 23:59:59"), dateOfBirth)); // ERROR! returns incorrect age=21 here
        assertEquals(21, getAge(df.parse("10.1.2021 00:00:01"), dateOfBirth));
    }
}
Espinosa
  • 2,132
  • 18
  • 22
1
public class CalculateAge { 

private int age;

private void setAge(int age){

    this.age=age;

}
public void calculateAge(Date date){

    Calendar calendar=Calendar.getInstance();

    Calendar calendarnow=Calendar.getInstance();    

    calendarnow.getTimeZone();

    calendar.setTime(date);

    int getmonth= calendar.get(calendar.MONTH);

    int getyears= calendar.get(calendar.YEAR);

    int currentmonth= calendarnow.get(calendarnow.MONTH);

    int currentyear= calendarnow.get(calendarnow.YEAR);

    int age = ((currentyear*12+currentmonth)-(getyears*12+getmonth))/12;

    setAge(age);
}
public int getAge(){

    return this.age;

}
A-312
  • 10,203
  • 4
  • 38
  • 66
0
/**
 * Compute from string date in the format of yyyy-MM-dd HH:mm:ss the age of a person.
 * @author Yaron Ronen
 * @date 04/06/2012  
 */
private int computeAge(String sDate)
{
    // Initial variables.
    Date dbDate = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");      

    // Parse sDate.
    try
    {
        dbDate = (Date)dateFormat.parse(sDate);
    }
    catch(ParseException e)
    {
        Log.e("MyApplication","Can not compute age from date:"+sDate,e);
        return ILLEGAL_DATE; // Const = -2
    }

    // Compute age.
    long timeDiff = System.currentTimeMillis() - dbDate.getTime();      
    int age = (int)(timeDiff / MILLI_SECONDS_YEAR);  // MILLI_SECONDS_YEAR = 31558464000L;

    return age; 
}
Yaron Ronen
  • 429
  • 4
  • 4
  • Not sure whether you really tested this one or not, but for others, this method has one flaw. if the today is the same month that your birth date is and today < birthday, it still shows actual age + 1, i.e., for eg if your bday is 7 September 1986, and today is 1 September 2013, it will show you 27 instead of 26. – Rahul Shelke Jun 13 '13 at 12:28
  • 2
    This cannot be true as number of milliseconds in a year is NOT CONSTANT. Leap years have one day more, that is much more milliseconds then others. For a 40ty year old person your algorithm may report birthday 9 - 10 days earlier then it really is! There are also leap seconds. – Espinosa Nov 11 '13 at 17:36
0

Here is the java code to calculate age in year, month and days.

public static AgeModel calculateAge(long birthDate) {
    int years = 0;
    int months = 0;
    int days = 0;

    if (birthDate != 0) {
        //create calendar object for birth day
        Calendar birthDay = Calendar.getInstance();
        birthDay.setTimeInMillis(birthDate);

        //create calendar object for current day
        Calendar now = Calendar.getInstance();
        Calendar current = Calendar.getInstance();
        //Get difference between years
        years = now.get(Calendar.YEAR) - birthDay.get(Calendar.YEAR);

        //get months
        int currMonth = now.get(Calendar.MONTH) + 1;
        int birthMonth = birthDay.get(Calendar.MONTH) + 1;

        //Get difference between months
        months = currMonth - birthMonth;

        //if month difference is in negative then reduce years by one and calculate the number of months.
        if (months < 0) {
            years--;
            months = 12 - birthMonth + currMonth;
        } else if (months == 0 && now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
            years--;
            months = 11;
        }

        //Calculate the days
        if (now.get(Calendar.DATE) > birthDay.get(Calendar.DATE))
            days = now.get(Calendar.DATE) - birthDay.get(Calendar.DATE);
        else if (now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
            int today = now.get(Calendar.DAY_OF_MONTH);
            now.add(Calendar.MONTH, -1);
            days = now.getActualMaximum(Calendar.DAY_OF_MONTH) - birthDay.get(Calendar.DAY_OF_MONTH) + today;
        } else {
            days = 0;
            if (months == 12) {
                years++;
                months = 0;
            }
        }
    }

    //Create new Age object
    return new AgeModel(days, months, years);
}
akshay
  • 4,941
  • 5
  • 34
  • 55
0

Easiest way without any libraries:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;
lxknvlk
  • 2,230
  • 20
  • 28
  • 1
    This code uses troublesome old date-time classes that are now legacy, supplanted by the java.time classes. Instead, use the modern classes built into Java: `ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() )`. See [correct Answer](https://stackoverflow.com/a/27738766/642706) – Basil Bourque Jul 21 '17 at 17:56
  • 1
    `DateUtils` is a library – Terran Oct 15 '19 at 13:47
0

With Java 8, we can calculate a person age with one line of code:

public int calCAge(int year, int month,int days){             
    return LocalDate.now().minus(Period.of(year, month, days)).getYear();         
}
Mam's
  • 225
  • 2
  • 5
-1
public int getAge(Date birthDate) {
    Calendar a = Calendar.getInstance(Locale.US);
    a.setTime(date);
    Calendar b = Calendar.getInstance(Locale.US);
    int age = b.get(YEAR) - a.get(YEAR);
    if (a.get(MONTH) > b.get(MONTH) || (a.get(MONTH) == b.get(MONTH) && a.get(DATE) > b.get(DATE))) {
        age--;
    }
    return age;
}
sinuhepop
  • 18,521
  • 15
  • 63
  • 103
-1
import java.io.*;

class AgeCalculator
{
    public static void main(String args[])
    {
        InputStreamReader ins=new InputStreamReader(System.in);
        BufferedReader hey=new BufferedReader(ins);

        try
        {
            System.out.println("Please enter your name: ");
            String name=hey.readLine();

            System.out.println("Please enter your birth date: ");
            String date=hey.readLine();

            System.out.println("please enter your birth month:");
            String month=hey.readLine();

            System.out.println("please enter your birth year:");
            String year=hey.readLine();

            System.out.println("please enter current year:");
            String cYear=hey.readLine();

            int bDate = Integer.parseInt(date);
            int bMonth = Integer.parseInt(month);
            int bYear = Integer.parseInt(year);
            int ccYear=Integer.parseInt(cYear);

            int age;

            age = ccYear-bYear;
            int totalMonth=12;
            int yourMonth=totalMonth-bMonth;

            System.out.println(" Hi " + name + " your are " + age + " years " + yourMonth + " months old ");
        }
        catch(IOException err)
        {
            System.out.println("");
        }
    }
}
DerMike
  • 13,362
  • 12
  • 45
  • 60
-1
public int getAge(String birthdate, String today){
    // birthdate = "1986-02-22"
    // today = "2014-09-16"

    // String class has a split method for splitting a string
    // split(<delimiter>)
    // birth[0] = 1986 as string
    // birth[1] = 02 as string
    // birth[2] = 22 as string
    // now[0] = 2014 as string
    // now[1] = 09 as string
    // now[2] = 16 as string
    // **birth** and **now** arrays are automatically contains 3 elements 
    // split method here returns 3 elements because of yyyy-MM-dd value
    String birth[] = birthdate.split("-");
    String now[] = today.split("-");
    int age = 0;

    // let us convert string values into integer values
    // with the use of Integer.parseInt(<string>)
    int ybirth = Integer.parseInt(birth[0]);
    int mbirth = Integer.parseInt(birth[1]);
    int dbirth = Integer.parseInt(birth[2]);

    int ynow = Integer.parseInt(now[0]);
    int mnow = Integer.parseInt(now[1]);
    int dnow = Integer.parseInt(now[2]);

    if(ybirth < ynow){ // has age if birth year is lesser than current year
        age = ynow - ybirth; // let us get the interval of birth year and current year
        if(mbirth == mnow){ // when birth month comes, it's ok to have age = ynow - ybirth if
            if(dbirth > dnow) // birth day is coming. need to subtract 1 from age. not yet a bday
                age--;
        }else if(mbirth > mnow){ age--; } // birth month is comming. need to subtract 1 from age            
    }

    return age;
}
Jhonie
  • 1
  • 1
  • Note: Date format is: yyyy-MM-dd. This is a generic code which is tested in jdk7... – Jhonie Sep 16 '14 at 01:38
  • 1
    It would help if you provided some comments or explain how exactly to use this code. Simply code dumping is usually discouraged, and the question asker may not understand your choices behind why you decided to code your method up this way. – rayryeng Sep 16 '14 at 01:40
  • @rayryeng: Jhonie has already added comments in the code. That is enough to understand. Please think and read before giving such a comment. – akshay Mar 30 '16 at 10:51
  • @Akshay that wasn't obvious to me. In hindsight it looked like he code dumped. I usually don't read comments. It'd be nice if those were removed from the body and placed separately as an explanation. That's my preference though and we can agree to disagree here.... That being said, I forgot I even wrote this comment as it was almost two years ago. – rayryeng Mar 30 '16 at 10:54
  • @rayryeng: The reason behind this comment was, writing negative comments discourage people from using such a nice forum. So, we should encourage them by giving positive comments. Bdw, no offense. Cheers!!! – akshay Mar 30 '16 at 10:57
  • @Akshay and with that I do agree. That comment was made when I was still a new user :). Cheers and thanks for your feedback. – rayryeng Mar 30 '16 at 11:06
-1
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.Period;

public class AgeCalculator1 {

    public static void main(String args[]) {
        LocalDate start = LocalDate.of(1970, 2, 23);
        LocalDate end = LocalDate.now(ZoneId.systemDefault());

        Period p = Period.between(start, end);
        //The output of the program is :
        //45 years 6 months and 6 days.
        System.out.print(p.getYears() + " year" + (p.getYears() > 1 ? "s " : " ") );
        System.out.print(p.getMonths() + " month" + (p.getMonths() > 1 ? "s and " : " and ") );
        System.out.print(p.getDays() + " day" + (p.getDays() > 1 ? "s.\n" : ".\n") );
    }//method main ends here.
}
Dilshad Rana
  • 148
  • 9
  • 3
    Thanks for participating in StackOverflow. A couple suggestions for you. [A] Please include some discussion with your Answer. StackOverflow.com is meant to be much more than just a code snippet collection. For example, note how your code is using the new java.time framework while most of the other answers are using java.util.Date and Joda-Time. [B] Please contrast your Answer with the [similar Answer](http://stackoverflow.com/a/27738766/642706) by Meno Hochschild which also uses java.time. Explain how yours is better or attacks a different angle on the problem. Or retract yours if not better. – Basil Bourque Aug 30 '15 at 01:03
-1

I appreciate all correct answers but this is the kotlin answer for the same question

I hope would be helpful to kotlin developers

fun calculateAge(birthDate: Date): Int {
        val now = Date()
        val timeBetween = now.getTime() - birthDate.getTime();
        val yearsBetween = timeBetween / 3.15576e+10;
        return Math.floor(yearsBetween).toInt()
    }
ramana vv
  • 1,141
  • 11
  • 21
-1
public int getAge(Date dateOfBirth) 
{
    Calendar now = Calendar.getInstance();
    Calendar dob = Calendar.getInstance();

    dob.setTime(dateOfBirth);

    if (dob.after(now)) 
    {
        throw new IllegalArgumentException("Can't be born in the future");
    }

    int age = now.get(Calendar.YEAR) - dob.get(Calendar.YEAR);

    if (now.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR)) 
    {
        age--;
    }

    return age;
}
Cuga
  • 16,782
  • 29
  • 106
  • 156
Stradivariuz
  • 2,443
  • 1
  • 17
  • 6