Como calculo a idade de alguém em Java?

147

Quero retornar uma idade em anos como int em um método Java. O que tenho agora é o seguinte, em que getBirthDate () retorna um objeto Date (com a data de nascimento ;-)):

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

    Date age = new Date(ageInMillis);

    return age.getYear();
}

Mas desde que getYear () está obsoleto, estou me perguntando se existe uma maneira melhor de fazer isso? Não tenho certeza se isso funciona corretamente, pois ainda não tenho testes de unidade.

nojevive
fonte
Mudei de idéia sobre isso: a outra pergunta só tem uma aproximação de anos entre datas, não uma idade realmente correta.
Cletus
Dado que ele está retornando um int, você pode esclarecer o que você quer dizer com idade "correta"?
12139 Brian Agnew
2
Date vs Calendar é um conceito fundamental que pode ser obtido através da leitura da documentação Java. Não consigo entender por que isso seria tão votado.
Demongolem
@demongolem ??? Data e calendário são facilmente entendidos ?! Não, não mesmo. Há um zilhão de perguntas sobre o assunto aqui no Stack Overflow. O projeto Joda-Time produziu uma das bibliotecas mais populares, para substituir aquelas classes problemáticas de data e hora. Mais tarde, Sun, Oracle e a comunidade JCP aceitaram o JSR 310 ( java.time ), admitindo que as classes herdadas eram irremediavelmente inadequadas. Para mais informações, consulte Tutorial da Oracle .
Basil Bourque

Respostas:

159

O JDK 8 torna isso fácil e 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;
        }
    }
}

Um teste JUnit para demonstrar seu 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 devem estar usando o JDK 8 agora. Todas as versões anteriores passaram o fim de suas vidas de suporte.

duffymo
fonte
10
A comparação DAY_OF_YEAR pode levar a resultados errados ao lidar com anos bissextos.
precisa saber é o seguinte
1
A variável dateOfBirth deve ser o objeto Date. Como posso criar um objeto Date com a data de nascimento?
Erick
Considerando que temos 9 anos e, caso o Java 8 seja usado, essa deve ser a solução a ser usada.
precisa saber é o seguinte
JDK 9 é a versão de produção atual. Mais verdadeiro do que nunca.
Duffymo
2
@SteveOh eu discordo. Prefiro não aceitar nulls, mas usar Objects.requireNonNull.
MC Emperor
170

Confira o Joda , que simplifica os cálculos de data / hora (o Joda também é a base das novas APIs de data / hora Java padrão, para que você aprenda uma API em breve).

Edição: Java 8 tem algo muito semelhante e vale a pena conferir.

por exemplo

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

que é tão simples quanto você poderia querer. O material pré-Java 8 é (como você identificou) um tanto pouco intuitivo.

Brian Agnew
fonte
2
@ HoàngLong: Do JavaDocs: "Esta classe não representa um dia, mas o instante em milissegundos à meia-noite. Se você precisar de uma classe que represente o dia inteiro, um Intervalo ou um LocalDate poderá ser mais adequado." Nós realmente não quero representar uma data aqui.
Jon Skeet
Se você quiser fazer da maneira que @JohnSkeet sugere, é assim: Years age = Years.yearsBetween (new LocalDate (getBirthDate ()), new LocalDate ());
Fletch
Não sei por que usei o DateMidnight e agora percebo que está obsoleto. Agora foi alterado para usar LocalDate
Brian Agnew
2
@IgorGanapolsky De fato, a principal diferença é: Joda-Time usa construtores, enquanto Java-8 e ThreetenBP usam métodos estáticos de fábrica. Para um bug sutil na maneira como o Joda-Time calcula a idade, observe minha resposta, onde forneci uma visão geral sobre o comportamento 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
cleto
fonte
Sim, a aula do calendário é terrível. Infelizmente, no trabalho, às vezes eu tenho que usá-lo: /. Obrigado Cletus por postar isso
Steve
1
Substitua Calendar.MONTH e Calendar.DAY_OF_MONTH com Calendar.DAY_OF_YEAR e vai pelo menos ser um pouco mais limpo
Tobbbe
@Tobbbe Se você nasceu em 1º de março de um ano bissexto, seu aniversário é em 1º de março do ano seguinte, e não em 2º. DAY_OF_YEAR não funcionará.
Airsource Ltd
42

Resposta moderna e visão geral

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

Observe que a expressão LocalDate.now()está implicitamente relacionada ao fuso horário do sistema (que geralmente é ignorado pelos usuários). Para maior clareza, geralmente é melhor usar o método sobrecarregado, now(ZoneId.of("Europe/Paris"))especificando um fuso horário explícito (aqui "Europa / Paris", por exemplo). Se o fuso horário do sistema for solicitado, minha preferência pessoal é escrever LocalDate.now(ZoneId.systemDefault())para tornar a relação com o fuso horário do sistema mais clara. Isso é mais trabalhoso, mas facilita a leitura.

b) Tempo de Joda

Observe que a solução Joda-Time proposta e aceita produz um resultado computacional diferente para as datas mostradas acima (um 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 isso um bug pequeno, mas a equipe da Joda tem uma visão diferente desse comportamento estranho e não deseja corrigi-lo (estranho porque o dia do mês da data de término é menor que o da data de início, portanto o ano deve ser um a menos). Veja também esta edição encerrada .

c) java.util.Calendar etc.

Para comparação, veja as várias outras respostas. Eu não recomendaria o uso dessas classes desatualizadas, porque o código resultante ainda é suscetível a erros em alguns casos exóticos e / ou muito complexo, considerando o fato de que a pergunta original parece tão simples. No ano de 2015, temos bibliotecas realmente melhores.

d) Sobre o Date4J:

A solução proposta é simples, mas às vezes falha em caso de anos bissextos. Apenas avaliar o dia do ano não é confiável.

e) Minha própria biblioteca Time4J :

Isso funciona de maneira semelhante à solução Java-8. Basta substituir LocalDatepor PlainDatee ChronoUnit.YEARSpor CalendarUnit.YEARS. No entanto, obter "hoje" requer uma referência explícita ao fuso horário.

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
fonte
1
Obrigado pela versão do Java 8! Economizei um tempo :) Agora só tenho que descobrir como extrair os meses restantes. Por exemplo, 1 ano e 1 mês. :)
thomas77
2
@ thomas77 Obrigado pela resposta, anos e meses combinados (e talvez dias) podem ser feitos usando `java.time.Period 'no Java-8. Se você também quiser levar em consideração outras unidades, como horas, o Java-8 não oferece uma solução.
Meno Hochschild 12/02
Obrigado novamente (e pela resposta rápida) :)
thomas77
1
Sugiro especificar um fuso horário ao usar LocalDate.now. Se omitido, o fuso horário padrão atual da JVM é aplicado implicitamente. Esse padrão pode mudar entre máquinas / sistemas operacionais / configurações e também pode a qualquer momento durante o tempo de execução por qualquer chamada de código setDefault. Eu recomendo ser específico, comoLocalDate.now( ZoneId.for( "America/Montreal" ) )
Basil Bourque
1
@GoCrafter_LP Sim, você pode aplicar o ThreetenABP simulando Java-8 ou Joda-Time-Android (de D. Lew) ou minha lib Time4A para versões Android mais antigas.
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;
}
Farhan Munir
fonte
2
Qual é o objetivo do cheque (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)? Parece inútil com a existência das comparações mês e dia / mês.
perfil completo de Jed Schaaf
13

Simplesmente uso os milissegundos em um valor constante de um ano para minha vantagem:

Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);
Lou Morda
fonte
2
Isso não é resposta precisa ... ano não é 3.156e + 10, mas 3.15576e + 10 (dia trimestre!)
Maher Abuthraa
1
Isso não trabalho, alguns anos são anos bissextos e têm um valor ms diferente
Greg Ennis
12

Se você estiver usando o GWT, ficará limitado ao uso do java.util.Date, eis um método que leva a data como números inteiros, mas ainda usa o 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
fonte
5

A resposta correta usando o JodaTime é:

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

Você pode até encurtá-lo em uma linha, se quiser. Copiei a ideia da resposta de BrianAgnew , mas acredito que isso é mais correto, como você vê nos comentários (e responde exatamente à pergunta).

Fletch
fonte
4

Com a biblioteca date4j :

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

Esta é uma versão melhorada da versão acima ... considerando que você deseja que a idade seja um 'int'. porque às vezes você não deseja preencher seu programa com várias 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;
}
cass
fonte
4

Talvez seja surpreendente notar que você não precisa saber quantos dias ou meses existem em um ano ou quantos dias existem nesses meses. Da mesma forma, você não precisa saber sobre anos bissextos, segundos bissextos ou qualquer outro desse material usando este método simples e 100% exato:

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
fonte
Estou procurando a solução para java 6 e 5. Isso é simples, mas preciso.
Jj Tuibeo
3

Tente copiar este no seu código e use o método para obter a idade.

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
fonte
A resposta apenas ao código é desencorajada. Seria melhor explicar por que esse código pode resolver a questão do OP.
121215
É um acéfalo realmente .. mas irá atualizar apenas para resolver a sua preocupação
Kevin
3

Eu uso este pedaço de código para cálculo de idade, espero que isso ajude ..sem bibliotecas usadas

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
fonte
2

Os campos nascimento e efeito são ambos campos de data:

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

Isso basicamente é uma modificação da solução de John O sem usar métodos depreciados. Passei bastante tempo tentando fazer com que o código dele funcionasse no meu código. Talvez isso salve os outros nesse momento.

John B
fonte
2
você pode explicar isso um pouco melhor? como isso calcula a idade?
Jonathan S. Fisher
1

Que tal 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;
}
Andre P.
fonte
Essa é uma sugestão muito fofa (quando você não está usando o Joda e não pode usar o Java 8), no entanto, o algoritmo está um pouco errado, porque você é 0 até que todo o primeiro ano passe. Portanto, você precisa adicionar um ano à data antes de iniciar o loop while.
Dagmar
1

String dateofbirthtem a data de nascimento. e formato é o que for (definido na seguinte linha):

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

Aqui está como formatar:

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

Variável ageStrterá os anos.

user1955658
fonte
1

Variante elegante, aparentemente correta , com registro de data e hora da solução Yaron Ronen.

Estou incluindo um teste de unidade para provar quando e por que não está correto . É impossível devido (possivelmente) a um número diferente de dias bissextos (e segundos) em qualquer diferença de carimbo de data / hora. A discrepância deve ser no máximo + -1 dia (e um segundo) para esse algoritmo, consulte test2 (), enquanto a solução de Yaron Ronen se baseia na suposição completamente constante detimeDiff / MILLI_SECONDS_YEAR pode diferir 10 dias para os 40 anos, mas essa variante também está incorreta.

É complicado, porque essa variante aprimorada, usando a fórmula diffAsCalendar.get(Calendar.YEAR) - 1970, retorna resultados corretos na maioria das vezes, como o número de anos bissextos em média o mesmo entre duas datas.

/**
 * 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
fonte
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;

}
Vahid Pooreftekhari
fonte
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
fonte
Não tenho certeza se você realmente testou este ou não, mas para outros, esse método tem uma falha. se hoje é o mesmo mês em que sua data de nascimento e hoje <aniversário, ele ainda mostra a idade real + 1, ou seja, por exemplo, se seu aniversário é 7 de setembro de 1986 e hoje é 1 de setembro de 2013, ele exibirá 27 # 26
srahul07 13/06
2
Isso não pode ser verdade, pois o número de milissegundos em um ano NÃO É CONSTANTE. Os anos bissextos têm mais um dia, ou seja, muito mais milissegundos que outros. Para uma pessoa de 40 anos, seu algoritmo pode relatar aniversário 9 a 10 dias antes, então é mesmo! Há também segundos bissextos.
Espinosa
0

Aqui está o código java para calcular a idade no ano, mês e dias.

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
fonte
0

Maneira mais fácil sem bibliotecas:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;
lxknvlk
fonte
1
Esse código usa classes de data e hora antigas problemáticas que agora são herdadas, substituídas pelas classes java.time. Em vez disso, use as classes modernas construídas em Java: ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() ). Veja a resposta correta
Basil Bourque
DateUtilsé uma biblioteca
Terran
0

Com o Java 8, podemos calcular a idade de uma pessoa com uma linha de código:

public int calCAge(int year, int month,int days){             
    return LocalDate.now().minus(Period.of(year, month, days)).getYear();         
}
Mam's
fonte
idade no ano ou no mês? que tal bebê no mês?
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;
}
Stradivariuz
fonte
como @sinuhepop notado "A comparação DAY_OF_YEAR pode levar a resultado errôneo quando se lida com os anos bissextos"
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("");
        }
    }
}
Surendar S
fonte
-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
fonte
Nota: O formato da data é: aaaa-MM-dd. Este é um código genérico que é testado em JDK7 ...
Jhonie
1
Ajudaria se você fornecesse alguns comentários ou explicasse exatamente como usar esse código. Simplesmente o despejo de código geralmente é desencorajado, e o responsável pela pergunta pode não entender suas escolhas por que você decidiu codificar seu método dessa maneira.
rayryeng 16/09/14
@rayryeng: Jhonie já adicionou comentários no código. Isso é suficiente para entender. Por favor, pense e leia antes de fazer um comentário.
akshay
@ Akshay que não era óbvio para mim. Em retrospectiva, parecia que o código foi despejado. Eu normalmente não leio comentários. Seria bom se eles fossem removidos do corpo e colocados separadamente como explicação. Essa é a minha preferência e podemos concordar em discordar aqui ... Dito isto, eu esqueci que até escrevi esse comentário, como era quase dois anos atrás.
rayryeng
@rayryeng: A razão por trás desse comentário foi que escrever comentários negativos desencoraja as pessoas a usarem um fórum tão bom. Portanto, devemos incentivá-los, dando comentários positivos. Bdw, sem ofensa. Felicidades!!!
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.
}
Dilshad Rana
fonte
3
Obrigado por participar do StackOverflow. Algumas sugestões para você. [A] Por favor inclua alguma discussão com sua resposta. StackOverflow.com deve ser muito mais do que apenas uma coleção de trechos de código. Por exemplo, observe como seu código está usando a nova estrutura java.time, enquanto a maioria das outras respostas está usando java.util.Date e Joda-Time. [B] Compare sua resposta com a resposta similar de Meno Hochschild, que também usa java.time. Explique como o seu é melhor ou ataca um ângulo diferente sobre o problema. Ou retraia o seu, se não melhor.
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;
}
sinuhepop
fonte
-1

Agradeço todas as respostas corretas, mas esta é a resposta kotlin para a mesma pergunta

Espero que seja útil para desenvolvedores 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()
    }
ramana vv
fonte
Parece um pouco tolo fazer essa matemática quando temos as classes java.time líderes do setor à nossa disposição.
Basil Bourque
Solicitações de OP em Java.
Terran