it-swarm.com.de

Wie berechne ich das Alter einer Person in Java?

Ich möchte ein Alter in Jahren als int in einer Java-Methode zurückgeben. Was ich jetzt habe, ist folgendes, wo getBirthDate () ein Date-Objekt (mit dem Geburtsdatum ;-)) zurückgibt:

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

    Date age = new Date(ageInMillis);

    return age.getYear();
}

Aber da getYear () veraltet ist, frage ich mich, ob es einen besseren Weg gibt, dies zu tun? Ich bin mir nicht mal sicher, ob das richtig funktioniert, da ich noch keine Unit-Tests habe.

128
nojevive

JDK 8 macht dies einfach und elegant:

public class AgeCalculator {

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

Ein JUnit-Test zum Nachweis seiner Verwendung: 

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

Jeder sollte jetzt JDK 8 verwenden. Alle früheren Versionen haben das Ende ihrer Supportlebensdauer überschritten.

135
duffymo

Check out Joda vereinfacht die Berechnung von Datum und Uhrzeit (Joda ist auch die Basis der neuen Standard-Java-API für Datums- und Zeitangaben, sodass Sie bald eine Standard-API lernen werden). 

BEARBEITEN: Java 8 hat etwas sehr ähnliches und lohnt sich.

z.B. 

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

das ist so einfach wie Sie wollen. Die Vorkenntnisse für Java 8 sind (wie Sie festgestellt haben) etwas unintuitiv.

165
Brian Agnew
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
41
cletus

Moderne Antwort und Überblick

a) Java-8 (Java.time-Paket)

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

Beachten Sie, dass der Ausdruck LocalDate.now() implizit mit der Systemzeitzone zusammenhängt (die von Benutzern oft übersehen wird). Aus Gründen der Übersichtlichkeit ist es in der Regel besser, die überladene Methode now(ZoneId.of("Europe/Paris")) zu verwenden, die eine explizite Zeitzone angibt (hier als Beispiel "Europa/Paris"). Wenn die Systemzeitzone angefordert wird, schreibe ich LocalDate.now(ZoneId.systemDefault()), um die Beziehung zur Systemzeitzone klarer zu machen. Dies ist mehr Schreibaufwand, erleichtert aber das Lesen.

b) Joda-Zeit

Bitte beachten Sie, dass die vorgeschlagene und akzeptierte Joda-Time-Lösung ein anderes Berechnungsergebnis für die oben angegebenen Daten ergibt (seltener Fall):

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

Ich halte das für einen kleinen Fehler, aber das Joda-Team hat eine andere Sicht auf dieses seltsame Verhalten und möchte es nicht beheben (seltsam, weil der Tag am Monat des Enddatums kleiner ist als das Startdatum, also sollte das Jahr sein.) einer weniger). Siehe auch diese geschlossene Ausgabe .

c) Java.util.Calendar usw.

Zum Vergleich siehe die verschiedenen anderen Antworten. Ich würde die Verwendung dieser veralteten Klassen nicht empfehlen, da der resultierende Code in einigen exotischen Fällen immer noch fehleranfällig und/oder viel zu komplex ist, wenn man bedenkt, dass die ursprüngliche Frage so einfach klingt. Im Jahr 2015 haben wir wirklich bessere Bibliotheken.

d) Über Date4J:

Die vorgeschlagene Lösung ist einfach, versagt jedoch manchmal in Schaltjahren. Es ist nicht zuverlässig, nur den Tag des Jahres auszuwerten.

e) Meine eigene Bibliothek Time4J:

Dies funktioniert ähnlich wie bei der Java-8-Lösung. Ersetzen Sie einfach LocalDate durch PlainDate und ChronoUnit.YEARS durch CalendarUnit.YEARS. Um "heute" zu erhalten, ist jedoch eine explizite Zeitzonenreferenz erforderlich.

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
36
Meno Hochschild
/**
 * 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;
}
17
Farhan Munir

Ich nutze einfach die Millisekunden in einem Jahr konstant zu meinem Vorteil:

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

Wenn Sie GWT verwenden, können Sie nur Java.util.Date verwenden. Hier ist eine Methode, die das Datum als Ganzzahl annimmt, aber trotzdem Java.util.Date verwendet:

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

Mit der date4j library:

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

Die richtige Antwort mit JodaTime lautet:

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

Sie können es sogar in eine Zeile kürzen, wenn Sie möchten. Ich habe die Idee aus BrianAgnews Antwort kopiert, aber ich glaube, dass dies korrekter ist, als Sie aus den Kommentaren dort sehen (und die Frage genau beantwortet).

4
Fletch

Versuchen Sie, diese in Ihren Code zu kopieren, und verwenden Sie dann die Methode, um das Alter zu ermitteln.

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

Ich benutze diesen Code für die Altersberechnung. Hoffe, das hilft. Keine Bibliotheken verwendet

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
Ameen Maheen

Dies ist eine verbesserte Version der obigen Version ... in Anbetracht der Tatsache, dass das Alter ein "int" sein soll. denn manchmal möchten Sie Ihr Programm nicht mit einer Reihe von Bibliotheken füllen.

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

Es ist vielleicht überraschend zu bemerken, dass Sie nicht wissen müssen, wie viele Tage oder Monate in einem Jahr oder wie viele Tage in diesen Monaten sind. Ebenso müssen Sie keine Schaltjahre, Schaltsekunden oder andere Zeiträume kennen von diesem Zeug mit dieser einfachen, 100% genauen Methode:

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

Die Felder birth und effect sind beide Datumsfelder: 

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

Dies ist im Wesentlichen eine Modifikation der Lösung von John O, ohne dass abgeschriebene Methoden verwendet werden. Ich habe ziemlich viel Zeit damit verbracht, zu versuchen, seinen Code in meinen Code zu integrieren. Vielleicht wird dies andere Zeit retten.

2
John B
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;

}
1

Stringdateofbirth hat das Geburtsdatum. und Format ist was (definiert in der folgenden Zeile):

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

So formatieren Sie:

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

Variable ageStr wird die Jahre haben.

1
user1955658

Ich schätze alle richtigen Antworten, aber dies ist die kotlin Antwort auf dieselbe Frage

Ich hoffe, es wäre hilfreich für Kotlin-Entwickler 

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()
    }
1
ramana vv

Elegante, scheinbar korrekte, zeitbasierte Differenzvariante der Yaron Ronen-Lösung.

Ich füge einen Unit-Test hinzu, um zu überprüfen, wann und warum es nicht korrekt ist. Es ist unmöglich (aufgrund möglicher) unterschiedlicher Anzahl von Schalttagen (und Sekunden) in einer Zeitstempeldifferenz. Die Abweichung sollte für diesen Algorithmus max + -1 Tag (und eine Sekunde) betragen (siehe test2 ()), wohingegen die Lösung von Yaron Ronen, die auf einer vollständig konstanten Annahme von timeDiff / MILLI_SECONDS_YEAR basiert, für einen 40. Lebensjahr 10 Tage abweichen kann. Diese Variante ist jedoch auch falsch .

Es ist schwierig, da diese verbesserte Variante mit der Formel diffAsCalendar.get(Calendar.YEAR) - 1970 die meiste Zeit korrekte Ergebnisse liefert, da die Anzahl der Schaltjahre im Durchschnitt zwischen zwei Datumsangaben gleich ist.

/**
 * 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
Espinosa

Was ist mit diesem?

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;
}
1
Andre P.

Hier ist der Java-Code zur Berechnung des Alters in Jahr, Monat und Tagen. 

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
akshay

Einfachster Weg ohne Bibliotheken:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;
0
lxknvlk
/**
 * 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; 
}
0
Yaron Ronen

Mit Java 8 können wir das Alter einer Person mit einer Codezeile berechnen:

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