¿Cómo calculo la edad de alguien en Java?


147

Quiero devolver una edad en años como int en un método Java. Lo que tengo ahora es lo siguiente donde getBirthDate () devuelve un objeto Date (con la fecha de nacimiento ;-)):

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

    Date age = new Date(ageInMillis);

    return age.getYear();
}

Pero dado que getYear () está en desuso, me pregunto si hay una mejor manera de hacer esto. Ni siquiera estoy seguro de que esto funcione correctamente, ya que no tengo pruebas unitarias en su lugar (todavía).


Cambié de opinión al respecto: la otra pregunta solo tiene una aproximación de años entre fechas, no una edad verdaderamente correcta.
cletus

Dado que está devolviendo un int, ¿puede aclarar lo que quiere decir con una edad 'correcta'?
Brian Agnew

2
Date vs Calendar es un concepto fundamental que se puede obtener de la lectura de la documentación de Java. No puedo entender por qué esto sería tan votado.
demongolem

@demongolem ??? ¿Fecha y calendario son fáciles de entender? No, en absoluto. Hay un millón de preguntas sobre el tema aquí en Stack Overflow. El proyecto Joda-Time produjo una de las bibliotecas más populares, para sustituir esas clases problemáticas de fecha y hora. Más tarde, Sun, Oracle y la comunidad JCP aceptaron JSR 310 ( java.time ), admitiendo que las clases heredadas eran irremediablemente inadecuadas. Para obtener más información, consulte Tutorial de Oracle .
Basil Bourque

Respuestas:


159

JDK 8 hace esto fácil y elegante:

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;
        }
    }
}

Una prueba JUnit para demostrar su uso:

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

Todos deberían estar usando JDK 8 por ahora. Todas las versiones anteriores han pasado el final de sus vidas de soporte.


10
La comparación DAY_OF_YEAR puede conducir a resultados erróneos cuando se trata de años bisiestos.
sinuhepop

1
La variable dateOfBirth tiene que ser un objeto Date. ¿Cómo puedo crear un objeto Date con la fecha de nacimiento?
Erick

En vista del hecho de que llevamos 9 años, y en caso de que se use Java 8, esta debería ser la solución a utilizar.
nojevive

JDK 9 es la versión de producción actual. Más cierto que nunca.
duffymo

2
@ SteveOh, no estoy de acuerdo. Preferiría no aceptar nulls en absoluto, sino usarlo Objects.requireNonNull.
MC Emperor

170

Eche un vistazo a Joda , que simplifica los cálculos de fecha / hora (Joda también es la base de la nueva API estándar de fecha / hora de Java, por lo que aprenderá una API que pronto será estándar).

EDITAR: Java 8 tiene algo muy similar y vale la pena echarle un vistazo.

p.ej

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

que es tan simple como podrías desear. El material anterior a Java 8 es (como ha identificado) algo poco intuitivo.


2
@ HoàngLong: De JavaDocs: "Esta clase no representa un día, sino el milisegundo instantáneo a la medianoche. Si necesita una clase que represente todo el día, entonces un Intervalo o un LocalDate pueden ser más adecuados". Realmente qué queremos representar una fecha aquí.
Jon Skeet

Si desea hacerlo de la manera @JohnSkeet sugiere, es así: Años de edad = Años.AñosEntre (nuevo LocalDate (getBirthDate ()), nuevo LocalDate ());
Fletch

No sé por qué usé DateMidnight, y noto que ahora está en desuso. Ahora cambiado para usar LocalDate
Brian Agnew


2
@IgorGanapolsky De hecho, la principal diferencia es: Joda-Time usa constructores mientras que Java-8 y ThreetenBP usan métodos estáticos de fábrica. Para un error sutil en la forma en que Joda-Time calcula la edad, mire mi respuesta donde he dado una visión general sobre el comportamiento de diferentes bibliotecas.
Meno Hochschild

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

Sí, la clase del calendario es terrible. Desafortunadamente, en el trabajo a veces tengo que usarlo: /. Gracias Cletus por publicar esto
Steve

1
Reemplace Calendar.MONTH y Calendar.DAY_OF_MONTH con Calendar.DAY_OF_YEAR y al menos estará un poco más limpio
Tobbbe

@Tobbbe Si naces el 1 de marzo en un año bisiesto, entonces tu cumpleaños es el 1 de marzo del año siguiente, no el 2do. DAY_OF_YEAR no funcionará.
Airsource Ltd

42

Respuesta moderna y resumen

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

Tenga en cuenta que la expresión LocalDate.now()está implícitamente relacionada con la zona horaria del sistema (que a menudo los usuarios pasan por alto). Para mayor claridad, generalmente es mejor usar el método sobrecargado que now(ZoneId.of("Europe/Paris"))especifica una zona horaria explícita (aquí "Europa / París" como ejemplo). Si se solicita la zona horaria del sistema, mi preferencia personal es escribir LocalDate.now(ZoneId.systemDefault())para aclarar la relación con la zona horaria del sistema. Esto es más esfuerzo de escritura pero facilita la lectura.

b) Joda-Time

Tenga en cuenta que la solución Joda-Time propuesta y aceptada produce un resultado de cálculo diferente para las fechas mostradas anteriormente (un caso raro), a saber:

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

Considero esto como un pequeño error, pero el equipo de Joda tiene una opinión diferente sobre este comportamiento extraño y no quiere solucionarlo (extraño porque el día del mes de la fecha de finalización es menor que el de la fecha de inicio, por lo que el año debería ser uno menos). Ver también este tema cerrado .

c) java.util.Calendar etc.

Para comparar, vea las otras respuestas. No recomendaría usar estas clases desactualizadas porque el código resultante todavía es propenso a errores en algunos casos exóticos y / o es demasiado complejo considerando el hecho de que la pregunta original suena muy simple. En el año 2015 tenemos bibliotecas realmente mejores.

d) Acerca de Date4J:

La solución propuesta es simple pero a veces fallará en caso de años bisiestos. Solo evaluar el día del año no es confiable.

e) Mi propia biblioteca Time4J :

Esto funciona de manera similar a la solución Java-8. Simplemente reemplace LocalDatepor PlainDatey ChronoUnit.YEARSpor CalendarUnit.YEARS. Sin embargo, obtener "hoy" requiere una referencia explícita de zona horaria.

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

1
¡Gracias por la versión de Java 8! Me ahorró algo de tiempo :) Ahora solo tengo que descubrir cómo extraer los meses restantes. Por ejemplo, 1 año y 1 mes. :)
thomas77

2
@ thomas77 Gracias por responder, se pueden combinar años y meses (y tal vez días) usando `java.time.Period 'en Java-8. Si también desea tener en cuenta otras unidades como horas, entonces Java-8 no ofrece una solución.
Meno Hochschild

Gracias de nuevo (y por la respuesta rápida) :)
thomas77

1
Sugiero especificar una zona horaria al usar LocalDate.now. Si se omite, la zona horaria predeterminada actual de la JVM se aplica implícitamente. Ese valor predeterminado puede cambiar entre máquinas / SO / configuraciones, y también puede hacerlo en cualquier momento durante el tiempo de ejecución mediante cualquier llamada de código setDefault. Recomiendo ser específico, comoLocalDate.now( ZoneId.for( "America/Montreal" ) )
Basil Bourque

1
@GoCrafter_LP Sí, puede aplicar ThreetenABP simulando Java-8, o Joda-Time-Android (de D. Lew) o mi lib Time4A para versiones de Android más antiguas.
Meno Hochschild

17
/**
 * 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;
}

2
¿Cuál es el propósito del cheque (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)? Parece inútil con la existencia de las comparaciones de mes y día de mes.
Jed Schaaf

13

Simplemente utilizo el valor constante de milisegundos en un año para mi ventaja:

Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);

2
Esta no es una respuesta precisa ... el año no es 3.156e + 10 sino 3.15576e + 10 (¡cuarto de día!)
Maher Abuthraa

1
Esto no funciona, algunos años son bisiestos y tienen un valor de ms diferente
Greg Ennis

12

Si está utilizando GWT, estará limitado a usar java.util.Date, aquí hay un método que toma la fecha como enteros, pero aún usa 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;
}

5

La respuesta correcta usando JodaTime es:

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

Incluso podría acortarlo en una línea si lo desea. Copié la idea de la respuesta de BrianAgnew , pero creo que esto es más correcto como se ve en los comentarios allí (y responde la pregunta exactamente).


4

Con la biblioteca date4j :

int age = today.getYear() - birthdate.getYear();
if(today.getDayOfYear() < birthdate.getDayOfYear()){
  age = age - 1; 
}

4

Esta es una versión mejorada de la anterior ... teniendo en cuenta que desea que la edad sea un 'int'. porque a veces no quieres llenar tu programa con un montón de bibliotecas.

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;
}

4

Quizás sea sorprendente notar que no necesita saber cuántos días o meses hay en un año o cuántos días hay en esos meses, del mismo modo, no necesita saber acerca de los años bisiestos, los segundos bisiestos o cualquier otro de esas cosas usando este método simple y 100% preciso:

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;
}

Estoy buscando una solución para Java 6 y 5. Esto es simple pero preciso.
Jj Tuibeo

3

Intente copiar este en su código, luego use el método para obtener la edad.

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;
}

Código solo se desaconseja la respuesta. Sería mejor explicar por qué este código puede abordar la pregunta OP.
рüффп

No es una obviedad en realidad ... pero se actualizará solo para abordar su preocupación
Kevin

3

Uso este código para calcular la edad, espero que esto ayude ... no se usan bibliotecas

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 ;
}

2

Los campos nacimiento y efecto son ambos campos de fecha:

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);

Esto básicamente es una modificación de la solución de John O sin usar métodos depreciados. Pasé bastante tiempo intentando que su código funcionara en mi código. Quizás esto salvará a otros ese tiempo.


2
¿Puedes explicar esto un poco mejor? ¿Cómo calcula esto la edad?
Jonathan S. Fisher

1

¿Qué hay de este?

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;
}

Esta es una sugerencia realmente linda (cuando no estás usando Joda y no puedes usar Java 8), sin embargo, el algoritmo está ligeramente equivocado porque estás 0 hasta que pase todo el primer año. Por lo tanto, debe agregar un año a la fecha antes de comenzar el ciclo while.
Dagmar

1

String dateofbirthTiene la fecha de nacimiento. y el formato es lo que sea (definido en la siguiente línea):

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

Aquí es cómo formatear:

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 ageStrtendrá los años.


1

Elegante, aparentemente correcta , variante basada en la diferencia de marca de tiempo de la solución de Yaron Ronen.

Incluyo una prueba unitaria para probar cuándo y por qué no es correcta . Es imposible debido (posiblemente) a un número diferente de días bisiestos (y segundos) en cualquier diferencia de marca de tiempo. La discrepancia debe ser max + -1 día (y un segundo) para este algoritmo, ver test2 (), mientras que la solución de Yaron Ronen basada en la suposición completamente constante de timeDiff / MILLI_SECONDS_YEARpuede diferir 10 días para un hombre de 40 años, sin embargo, esta variante también es incorrecta.

Es complicado, porque esta variante mejorada, usando la fórmula diffAsCalendar.get(Calendar.YEAR) - 1970, devuelve resultados correctos la mayor parte del tiempo, como número de años bisiestos en promedio igual entre dos fechas.

/**
 * 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));
    }
}

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;

}

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; 
}

No estoy seguro si realmente probó este o no, pero para otros, este método tiene un defecto. si hoy es el mismo mes en que es su fecha de nacimiento y hoy <cumpleaños, todavía muestra la edad real + 1, es decir, por ejemplo, si su cumpleaños es el 7 de septiembre de 1986 y hoy es el 1 de septiembre de 2013, le mostrará 27 en su lugar de 26.
srahul07

2
Esto no puede ser cierto ya que el número de milisegundos en un año NO ES CONSTANTE. Los años bisiestos tienen un día más, eso es mucho más milisegundos que otros. ¡Para una persona de 40 años, su algoritmo puede informar el cumpleaños 9-10 días antes de lo que realmente es! También hay segundos bisiestos.
Espinosa

0

Aquí está el código de Java para calcular la edad en año, mes y días.

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

0

La forma más fácil sin bibliotecas:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;

1
Este código utiliza clases problemáticas de fecha y hora antiguas que ahora son heredadas, suplantadas por las clases java.time. En su lugar, utilice las clases modernas construidas en Java: ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() ). Ver respuesta correcta
Basil Bourque

DateUtilses una biblioteca
Terran

0

Con Java 8, podemos calcular la edad de una persona con una línea de código:

public int calCAge(int year, int month,int days){             
    return LocalDate.now().minus(Period.of(year, month, days)).getYear();         
}

edad en año o en mes? ¿Qué tal un bebé en un mes?
Gumuruh

-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;
}

como @sinuhepop notó "La comparación DAY_OF_YEAR puede conducir a resultados erróneos cuando se trata de años bisiestos"
Krzysztof Kot

-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("");
        }
    }
}

-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;
}

Nota: El formato de fecha es: aaaa-MM-dd. Este es un código genérico que se probó en JDK7 ...
Jhonie

1
Sería útil si proporcionara algunos comentarios o explicara cómo usar exactamente este código. Por lo general, se desaconseja simplemente el volcado de código, y el que hace la pregunta puede no entender sus opciones detrás de por qué decidió codificar su método de esta manera.
rayryeng

@rayryeng: Jhonie ya ha agregado comentarios en el código. Eso es suficiente para entender. Piensa y lee antes de hacer un comentario.
akshay

@Akshay eso no era obvio para mí. En retrospectiva, parecía que el código había sido arrojado. Usualmente no leo comentarios. Sería bueno si se quitaran del cuerpo y se colocaran por separado como explicación. Sin embargo, esa es mi preferencia y podemos estar de acuerdo en no estar de acuerdo aquí ... Dicho esto, olvidé que incluso escribí este comentario, ya que fue hace casi dos años.
rayryeng

@rayryeng: La razón detrás de este comentario fue que escribir comentarios negativos desalienta a las personas a usar un foro tan agradable. Por lo tanto, debemos alentarlos dando comentarios positivos. Bdw, sin ofender. ¡¡¡Salud!!!
akshay

-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.
}

3
Gracias por participar en StackOverflow. Un par de sugerencias para ti. [A] Incluya una discusión con su respuesta. StackOverflow.com está destinado a ser mucho más que una simple colección de fragmentos de código. Por ejemplo, observe cómo su código usa el nuevo marco java.time, mientras que la mayoría de las otras respuestas usan java.util.Date y Joda-Time. [B] Por favor, compara tu respuesta con la respuesta similar de Meno Hochschild que también usa java.time. Explica cómo el tuyo es mejor o ataca un ángulo diferente del problema. O retraiga el suyo si no mejor.
Basil Bourque

-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;
}

-1

Agradezco todas las respuestas correctas, pero esta es la respuesta de Kotlin para la misma pregunta.

Espero que sea útil para los desarrolladores de Kotlin

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

Parece bastante tonto estar haciendo tales matemáticas cuando tenemos las clases java.time líderes en la industria a nuestra disposición.
Basil Bourque

Solicitudes de OP en Java.
Terran
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.