Come posso calcolare l'età di qualcuno in Java?


147

Voglio restituire un'età in anni come int in un metodo Java. Quello che ho ora è il seguente in cui getBirthDate () restituisce un oggetto Date (con la data di nascita ;-)):

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

    Date age = new Date(ageInMillis);

    return age.getYear();
}

Ma poiché getYear () è deprecato, mi chiedo se c'è un modo migliore per farlo? Non sono nemmeno sicuro che funzioni correttamente, dal momento che non ho ancora effettuato test unitari.


Ho cambiato idea su quello: l'altra domanda ha solo un'approssimazione di anni tra le date, non un'età veramente corretta.
cletus,

Dato che sta restituendo un int, puoi chiarire cosa intendi per età "corretta"?
Brian Agnew,

2
Date vs Calendar è un concetto fondamentale che può essere ricavato dalla lettura della documentazione Java. Non riesco a capire perché questo dovrebbe essere votato così tanto.
demongolem,

@demongolem ??? Data e calendario sono facilmente comprensibili ?! No, per niente. Ci sono miliardi di domande sull'argomento qui su Stack Overflow. Il progetto Joda-Time ha prodotto una delle biblioteche più popolari, in sostituzione di quelle fastidiose lezioni di data e ora. Successivamente, Sun, Oracle e la comunità JCP hanno accettato JSR 310 ( java.time ), ammettendo che le classi legacy erano irrimediabilmente inadeguate. Per ulteriori informazioni, consultare Tutorial di Oracle .
Basil Bourque,

Risposte:


159

JDK 8 lo rende semplice ed 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;
        }
    }
}

Un test JUnit per dimostrarne l'utilizzo:

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

Ormai tutti dovrebbero usare JDK 8. Tutte le versioni precedenti hanno superato la fine delle loro vite di supporto.


10
Il confronto DAY_OF_YEAR può portare a risultati errati quando si affrontano gli anni bisestili.
sinuhepop,

1
La variabile dateOfBirth deve essere oggetto Date. Come posso creare un oggetto Date con la data di nascita?
Erick,

In considerazione del fatto che sono trascorsi 9 anni e nel caso in cui venga utilizzato Java 8, questa dovrebbe essere la soluzione da utilizzare.
Nojevive,

JDK 9 è l'attuale versione di produzione. Più vero che mai.
duffymo,

2
@SteveOh non sono d'accordo. Preferirei non accettare nullaffatto, ma invece userei Objects.requireNonNull.
MC Emperor

170

Dai un'occhiata a Joda , che semplifica i calcoli di data / ora (Joda è anche la base delle nuove API standard di data / ora di Java, quindi imparerai presto un'API standard).

EDIT: Java 8 ha qualcosa di molto simile e vale la pena dare un'occhiata.

per esempio

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

che è semplice come potresti desiderare. La roba pre-Java 8 è (come hai identificato) in qualche modo poco intuitiva.


2
@ HoàngLong: Da JavaDocs: "Questa classe non rappresenta un giorno, ma l'istante di millisecondo a mezzanotte. Se hai bisogno di una classe che rappresenti l'intero giorno, allora un intervallo o un LocalDate potrebbero essere più adatti." Abbiamo davvero cosa vogliamo rappresentare una data qui.
Jon Skeet

Se vuoi farlo come suggerisce @JohnSkeet, è così: Years age = Years.yearsBetween (new LocalDate (getBirthDate ()), new LocalDate ());
Fletch,

Non so perché ho usato DateMidnight e noto che ora è obsoleto. Ora modificato per utilizzare LocalDate
Brian Agnew il


2
@IgorGanapolsky In effetti la differenza principale è: Joda-Time usa i costruttori mentre Java-8 e ThreetenBP usano metodi statici di fabbrica. Per un bug sottile nel modo in cui Joda-Time calcola l'età, per favore guarda la mia risposta in cui ho dato una panoramica sul comportamento di diverse librerie.
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 lezione di calendario è terribile. Sfortunatamente, a lavoro a volte devo usarlo: /. Grazie Cletus per aver pubblicato questo post
Steve

1
Sostituisci Calendar.MONTH e Calendar.DAY_OF_MONTH con Calendar.DAY_OF_YEAR e sarà almeno un po 'più pulito
Tobbbe,

@Tobbbe Se sei nato il 1 ° marzo in un anno bisestile, il tuo compleanno è il 1 ° marzo dell'anno successivo, non il 2 °. DAY_OF_YEAR non funzionerà.
Airsource Ltd,

42

Risposta moderna e panoramica

a) Java-8 (pacchetto java.time)

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

Si noti che l'espressione LocalDate.now()è implicitamente correlata al fuso orario del sistema (che viene spesso trascurato dagli utenti). Per chiarezza è generalmente meglio usare il metodo sovraccarico now(ZoneId.of("Europe/Paris"))specificando un fuso orario esplicito (qui "Europa / Parigi" come esempio). Se viene richiesto il fuso orario del sistema, la mia preferenza personale è quella di scrivere LocalDate.now(ZoneId.systemDefault())per rendere più chiara la relazione con il fuso orario del sistema. Questo è più sforzo di scrittura ma rende più facile la lettura.

b) Joda-Time

Si noti che la soluzione Joda-Time proposta e accettata produce un risultato di calcolo diverso per le date indicate sopra (un caso raro), vale a dire:

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

Lo considero un piccolo bug ma il team di Joda ha una visione diversa di questo strano comportamento e non vuole risolverlo (strano perché il giorno del mese della data di fine è più piccolo della data di inizio, quindi l'anno dovrebbe essere uno in meno). Vedi anche questo numero chiuso .

c) java.util.Calendario ecc.

Per un confronto vedi le altre risposte. Non consiglierei affatto di usare queste classi obsolete perché il codice risultante è ancora soggetto a errori in alcuni casi esotici e / o in modo troppo complesso considerando il fatto che la domanda originale sembra così semplice. Nel 2015 abbiamo biblioteche davvero migliori.

d) Informazioni su Date4J:

La soluzione proposta è semplice ma a volte fallirà in caso di anni bisestili. La valutazione del giorno dell'anno non è affidabile.

e) La mia libreria Time4J :

Funziona in modo simile alla soluzione Java-8. Basta sostituire LocalDateentro PlainDatee ChronoUnit.YEARSper CalendarUnit.YEARS. Tuttavia, ottenere "oggi" richiede un riferimento di fuso orario esplicito.

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
Grazie per la versione Java 8! Mi hai salvato un po 'di tempo :) Ora devo solo capire come estrarre i mesi rimanenti. Ad esempio 1 anno e 1 mese. :)
thomas77,

2
@ thomas77 Grazie per la risposta, è possibile combinare anni e mesi (e forse giorni) usando `java.time.Period 'in Java-8. Se vuoi anche prendere in considerazione altre unità come ore, Java-8 non offre una soluzione.
Meno Hochschild,

Grazie ancora (e per la rapida risposta) :)
thomas77

1
Suggerisco di specificare un fuso orario durante l'utilizzo LocalDate.now. Se omesso, l'attuale fuso orario predefinito della JVM viene applicato implicitamente. Tale impostazione predefinita può cambiare tra macchine / sistemi operativi / impostazioni e può anche in qualsiasi momento durante il runtime da qualsiasi chiamata di codice setDefault. Consiglio di essere specifico, come ad esempioLocalDate.now( ZoneId.for( "America/Montreal" ) )
Basil Bourque,

1
@GoCrafter_LP Sì, è possibile applicare ThreetenABP simulando Java-8 o Joda-Time-Android (da D. Lew) o la mia lib Time4A per versioni Android precedenti.
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
Qual è lo scopo del controllo (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)? Sembra inutile con l'esistenza dei confronti tra mese e dayofmonth.
Jed Schaaf

13

Uso semplicemente i millisecondi in un valore costante dell'anno a mio vantaggio:

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

2
Questa non è una risposta precisa ... l'anno non è 3.156e + 10 ma 3.15576e + 10 (quarto giorno!)
Maher Abuthraa

1
Questo non funziona, alcuni anni sono un anno bisestile e hanno un valore msec diverso
Greg Ennis

12

Se stai usando GWT sarai limitato all'utilizzo di java.util.Date, ecco un metodo che accetta la data come numeri interi, ma utilizza comunque 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 risposta corretta utilizzando JodaTime è:

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

Se lo desideri, potresti anche accorciarlo in una riga. Ho copiato l'idea dalla risposta di BrianAgnew , ma credo che sia più corretto come vedi dai commenti lì (e risponde esattamente alla domanda).


4

Con la libreria date4j :

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

4

Questa è una versione migliorata di quella sopra ... considerando che vuoi che l'età sia un 'int'. perché a volte non vuoi riempire il tuo programma con un mucchio di librerie.

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

È forse sorprendente notare che non è necessario sapere quanti giorni o mesi ci sono in un anno o quanti giorni ci sono in quei mesi, allo stesso modo, non è necessario conoscere anni bisestili, secondi bisestili o qualsiasi di quella roba usando questo semplice metodo accurato al 100%:

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

Sto cercando una soluzione per Java 6 e 5. Questo è semplice ma accurato.
Jj Tuibeo,

3

Prova a copiarlo nel tuo codice, quindi usa il metodo per ottenere l'età.

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

La sola risposta al codice è scoraggiata. Sarebbe meglio spiegare perché questo codice può rispondere alla domanda OP.
рüффп,

In realtà non è un gioco da ragazzi ... ma si aggiornerà solo per rispondere alla tua preoccupazione
Kevin

3

Uso questo pezzo di codice per il calcolo dell'età, spero che questo aiuti .. nessuna libreria usata

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

I campi nascita ed effetto sono entrambi campi 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);

Questa in sostanza è una modifica della soluzione di John O senza utilizzare metodi ammortizzati. Ho trascorso un bel po 'di tempo cercando di far funzionare il suo codice nel mio codice. Forse questo salverà gli altri quel tempo.


2
puoi spiegarlo un po 'meglio? come si calcola l'età?
Jonathan S. Fisher,

1

Che dire di questo?

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

Questo è un suggerimento davvero carino (quando non stai usando Joda e non puoi usare Java 8) tuttavia l'algoritmo è leggermente sbagliato perché sei 0 fino a quando non passa tutto il primo anno. Quindi è necessario aggiungere un anno alla data prima di iniziare il ciclo while.
Dagmar,

1

String dateofbirthha la data di nascita. e il formato è qualunque (definito nella riga seguente):

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

Ecco come formattare:

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

La variabile ageStravrà gli anni.


1

Elegante, apparentemente corretta , variante basata sulla differenza di data e ora della soluzione Yaron Ronen.

Sto includendo un test unitario per dimostrare quando e perché non è corretto . È impossibile a causa (forse) di un numero diverso di giorni bisestili (e secondi) in qualsiasi differenza di data / ora. La discrepanza dovrebbe essere massima di + -1 giorno (e un secondo) per questo algoritmo, vedi test2 (), mentre la soluzione Yaron Ronen basata su un'assunzione completamente costante timeDiff / MILLI_SECONDS_YEARpuò differire di 10 giorni per un 40enne, tuttavia questa variante non è corretta.

È difficile, perché questa variante migliorata, usando la formula diffAsCalendar.get(Calendar.YEAR) - 1970, restituisce i risultati corretti il ​​più delle volte, dato che il numero di anni bisestili è in media lo stesso tra due date.

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

Non sono sicuro di averlo testato o meno, ma per altri questo metodo ha un difetto. se oggi è lo stesso mese in cui è la tua data di nascita e oggi <compleanno, mostra ancora l'età effettiva + 1, vale a dire, ad esempio, se il tuo compleanno è il 7 settembre 1986 e oggi è il 1 settembre 2013, invece ti mostrerà 27 del 26.
srahul07,

2
Questo non può essere vero in quanto il numero di millisecondi in un anno NON È COSTANTE. Gli anni bisestili hanno un giorno in più, che è molto più millisecondi di altri. Per una persona di 40 anni il tuo algoritmo potrebbe riportare il compleanno 9 - 10 giorni prima, quindi lo è davvero! Ci sono anche secondi bisestili.
Espinosa,

0

Ecco il codice java per calcolare l'età in anno, mese e giorni.

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

Il modo più semplice senza librerie:

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

1
Questo codice utilizza vecchie classi problematiche di data e ora che sono ora legacy, soppiantate dalle classi java.time. Invece, utilizzare le classi moderni costruiti in Java: ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() ). Vedi risposta corretta
Basil Bourque,

DateUtilsè una biblioteca
Terran,

0

Con Java 8, possiamo calcolare l'età di una persona con una riga di codice:

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

età in anno o in mese? che ne dici di un bambino al mese?
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;
}

come ha notato @sinuhepop "Il confronto DAY_OF_YEAR può portare a risultati errati quando si ha a che fare con anni bisestili"
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: il formato della data è: aaaa-MM-gg. Questo è un codice generico che viene testato in jdk7 ...
Jhonie,

1
Sarebbe utile se fornissi alcuni commenti o spiegassi come utilizzare esattamente questo codice. Il semplice codice di dumping è generalmente sconsigliato e la domanda che si pone potrebbe non comprendere le tue scelte alla base del perché hai deciso di codificare il tuo metodo in questo modo.
Rayryeng,

@rayryeng: Jhonie ha già aggiunto commenti nel codice. Questo è abbastanza per capire. Ti preghiamo di pensare e leggere prima di dare un commento del genere.
akshay,

@Akshay non era ovvio per me. Con il senno di poi, sembrava che il codice fosse stato scaricato. Di solito non leggo i commenti. Sarebbe bello se quelli fossero rimossi dal corpo e collocati separatamente come spiegazione. Questa è la mia preferenza e possiamo concordare di non essere d'accordo qui .... Detto questo, ho dimenticato di aver persino scritto questo commento com'era quasi due anni fa.
Rayryeng,

@rayryeng: Il motivo dietro questo commento è stato, scrivere commenti negativi scoraggia le persone dall'usare un forum così bello. Quindi, dovremmo incoraggiarli dando commenti positivi. Bdw, senza offesa. Saluti!!!
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
Grazie per aver partecipato a StackOverflow. Un paio di suggerimenti per te. [A] Includi alcune discussioni con la tua risposta. StackOverflow.com è pensato per essere molto più di una semplice raccolta di frammenti di codice. Ad esempio, nota come il tuo codice utilizza il nuovo framework java.time mentre la maggior parte delle altre risposte utilizza java.util.Date e Joda-Time. [B] Contrasta la tua risposta con la risposta simile di Meno Hochschild che utilizza anche java.time. Spiega come il tuo è migliore o attacca una diversa angolazione sul problema. Oppure ritira il tuo se non meglio.
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

Apprezzo tutte le risposte corrette, ma questa è la risposta kotlin per la stessa domanda

Spero possa essere utile per gli sviluppatori di 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()
    }

Sembra piuttosto sciocco fare questo tipo di matematica quando abbiamo a disposizione le classi java.time leader del settore .
Basil Bourque

Richieste OP in Java.
Terran
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.