How do I calculate someone's age in Java? How do I calculate someone's age in Java? java java

How do I calculate someone's age in Java?


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.


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.


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 argsYears 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