Wie berechne ich das Alter einer Person in Java?

146

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

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 einmal sicher, ob dies richtig funktioniert, da ich (noch) keine Unit-Tests durchgeführt habe.

nojevive
quelle
Das hat meine Meinung geändert: Die andere Frage hat nur eine Annäherung an die Jahre zwischen den Daten, kein wirklich korrektes Alter.
Cletus
Können Sie angesichts der Tatsache, dass er einen Int zurückgibt, klarstellen, was Sie unter einem „richtigen“ Alter verstehen?
Brian Agnew
2
Datum gegen Kalender ist ein grundlegendes Konzept, das sich aus dem Lesen der Java-Dokumentation ableiten lässt. Ich kann nicht verstehen, warum dies so positiv bewertet würde.
Demongolem
@demongolem ??? Datum und Kalender sind leicht zu verstehen?! Nein überhaupt nicht. Es gibt zig Fragen zu diesem Thema hier auf Stapelüberlauf. Das Joda-Time-Projekt produzierte eine der beliebtesten Bibliotheken, um diese lästigen Datums- und Zeitklassen zu ersetzen. Später akzeptierten Sun, Oracle und die JCP-Community JSR 310 ( java.time ) und gaben zu , dass die Legacy-Klassen hoffnungslos unzureichend waren. Weitere Informationen finden Sie im Tutorial von Oracle .
Basil Bourque

Antworten:

159

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, um seine Verwendung zu demonstrieren:

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 ihres Support-Lebens überschritten.

Duffymo
quelle
10
Der DAY_OF_YEAR-Vergleich kann bei Schaltjahren zu fehlerhaften Ergebnissen führen.
Sinuhepop
1
Die Variable dateOfBirth muss ein Date-Objekt sein. Wie kann ich ein Datumsobjekt mit dem Geburtsdatum erstellen?
Erick
Angesichts der Tatsache, dass wir 9 Jahre alt sind und Java 8 verwendet wird, sollte dies die zu verwendende Lösung sein.
Nojevive
JDK 9 ist die aktuelle Produktionsversion. Mehr wahr als je zuvor.
Duffymo
2
@SteveOh Ich bin anderer Meinung. Ich würde lieber nulls überhaupt nicht akzeptieren , sondern verwenden Objects.requireNonNull.
MC Emperor
170

Schauen Sie sich Joda an , das die Datums- / Zeitberechnung vereinfacht (Joda ist auch die Grundlage der neuen Standard-Java-Datums- / Zeit-API, sodass Sie eine baldige Standard-API lernen werden).

EDIT: Java 8 hat etwas sehr ähnliches und ist einen Besuch wert.

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 könnten. Das Pre-Java 8-Zeug ist (wie Sie identifiziert haben) etwas unintuitiv.

Brian Agnew
quelle
2
@ HoàngLong: Aus den JavaDocs: "Diese Klasse repräsentiert keinen Tag, sondern den Millisekunden-Moment um Mitternacht. Wenn Sie eine Klasse benötigen, die den ganzen Tag repräsentiert, ist möglicherweise ein Intervall oder ein lokales Datum besser geeignet." Wir wirklich tun wollen hier ein Datum darzustellen.
Jon Skeet
Wenn Sie es so machen möchten, wie es @JohnSkeet vorschlägt, ist es folgendermaßen: Jahre age = Years.yearsBetween (neues LocalDate (getBirthDate ()), neues LocalDate ());
Fletch
Ich weiß nicht, warum ich DateMidnight verwendet habe, und ich stelle fest, dass es jetzt veraltet ist. Jetzt geändert, um LocalDate
Brian Agnew
2
@IgorGanapolsky In der Tat ist der Hauptunterschied: Joda-Time verwendet Konstruktoren, während Java-8 und ThreetenBP statische Factory-Methoden verwenden. Für einen subtilen Fehler bei der Berechnung des Alters durch Joda-Time schauen Sie sich bitte meine Antwort an, in der ich einen Überblick über das Verhalten verschiedener Bibliotheken gegeben habe.
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
Cletus
quelle
Ja, die Kalenderklasse ist schrecklich. Leider muss ich es bei der Arbeit manchmal benutzen: /. Vielen Dank an Cletus für die Veröffentlichung
Steve
1
Ersetzen Sie Calendar.MONTH und Calendar.DAY_OF_MONTH durch Calendar.DAY_OF_YEAR und es wird zumindest ein bisschen sauberer sein
Tobbbe
@Tobbbe Wenn Sie am 1. März eines Schaltjahres geboren sind, haben Sie am 1. März des folgenden Jahres Geburtstag, nicht am 2. März. DAY_OF_YEAR funktioniert nicht.
Airsource Ltd
42

Moderne Antwort und Übersicht

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 häufig übersehen wird). Aus Gründen der Übersichtlichkeit ist es im Allgemeinen besser, die überladene Methode zu verwenden, die now(ZoneId.of("Europe/Paris"))eine explizite Zeitzone angibt (hier "Europa / Paris" als Beispiel). Wenn die Systemzeitzone angefordert wird, ist es meine persönliche Präferenz, zu schreibenLocalDate.now(ZoneId.systemDefault()) , um die Beziehung zur Systemzeitzone klarer zu machen. Dies ist mehr Schreibaufwand, erleichtert jedoch 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 liefert (ein seltener Fall), nämlich:

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 betrachte dies als einen kleinen Fehler, aber das Joda-Team sieht dieses seltsame Verhalten anders und möchte es nicht beheben (seltsam, weil der Tag des Monats des Enddatums kleiner als der des Startdatums ist, 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 überhaupt 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, scheitert jedoch manchmal im Falle von Schaltjahren. Nur den Tag des Jahres auszuwerten, ist nicht zuverlässig.

e) Meine eigene Bibliothek Time4J :

Dies funktioniert ähnlich wie bei der Java-8-Lösung. Einfach LocalDatenach PlainDateund ChronoUnit.YEARSnach ersetzen 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
Meno Hochschild
quelle
1
Vielen Dank für die Java 8-Version! Hat mir etwas Zeit gespart :) Jetzt muss ich nur noch herausfinden, wie man verbleibende Monate extrahiert. ZB 1 Jahr und 1 Monat. :)
Thomas77
2
@ thomas77 Danke für die Antwort, kombinierte Jahre und Monate (und vielleicht Tage) können mit `java.time.Period 'in Java-8 durchgeführt werden. Wenn Sie auch andere Einheiten wie Stunden berücksichtigen möchten, bietet Java-8 keine Lösung.
Meno Hochschild
Nochmals vielen
1
Ich schlage vor , bei der Verwendung eine Zeitzone anzugebenLocalDate.now . Wenn nicht angegeben, wird implizit die aktuelle Standardzeitzone der JVM angewendet. Diese Standardeinstellung kann sich zwischen Maschinen / Betriebssystemen / Einstellungen ändern und kann jederzeit zur Laufzeit durch einen beliebigen Codeaufruf geändert werden setDefault. Ich empfehle, spezifisch zu sein, wieLocalDate.now( ZoneId.for( "America/Montreal" ) )
Basil Bourque
1
@GoCrafter_LP Ja, Sie können ThreetenABP, das Java-8 simuliert, oder Joda-Time-Android (von D. Lew) oder meine lib Time4A für solche älteren Android-Versionen anwenden.
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
quelle
2
Was ist der Zweck der Prüfung (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)? Es scheint sinnlos mit der Existenz der Vergleiche von Monat und Tag des Monats.
Jed Schaaf
12

Wenn Sie GWT verwenden, können Sie nur java.util.Date verwenden. Hier ist eine Methode, die das Datum als Ganzzahl verwendet, aber dennoch 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;
}
Craigo
quelle
12

Ich benutze einfach die Millisekunden in einem Jahr konstanten Wert 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);
Lou Morda
quelle
2
Dies ist keine genaue Antwort ... Jahr ist nicht 3.156e + 10, sondern 3.15576e + 10 (Vierteltag!)
Maher Abuthraa
1
Dies funktioniert nicht, einige Jahre sind Schaltjahr und haben einen anderen ms-Wert
Greg Ennis
5

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, wie Sie aus den Kommentaren dort sehen (und es beantwortet die Frage genau).

Befiedern
quelle
4

Mit der date4j- Bibliothek:

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

Dies ist eine verbesserte Version der oben genannten ... wenn man bedenkt, dass das Alter ein "int" sein soll. weil Sie manchmal Ihr Programm nicht mit einer Reihe von Bibliotheken füllen möchten.

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
quelle
4

Es ist vielleicht überraschend zu bemerken, dass Sie nicht wissen müssen, wie viele Tage oder Monate es in einem Jahr gibt oder wie viele Tage in diesen Monaten sind. Ebenso müssen Sie nichts über Schaltjahre, Schaltsekunden oder andere wissen 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;
}
Weston
quelle
Ich suche nach einer Lösung für Java 6 und 5. Dies ist einfach, aber genau.
Jj Tuibeo
3

Versuchen Sie, diesen 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;
}
Kevin
quelle
Nur Code-Antworten werden nicht empfohlen. Es wäre besser zu erklären, warum dieser Code die OP-Frage beantworten kann.
рüффп
Es ist eigentlich ein Kinderspiel .. aber wird aktualisiert, nur um Ihre Bedenken auszuräumen
Kevin
3

Ich benutze diesen Code für die Altersberechnung. Ich 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 ;
}
Ameen Maheen
quelle
2

Die Felder Geburt und Wirkung 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 Grunde eine Modifikation der Lösung von John O ohne Verwendung abgeschriebener Methoden. Ich habe ziemlich viel Zeit damit verbracht, seinen Code in meinem Code zum Laufen zu bringen. Vielleicht spart dies anderen diese Zeit.

John B.
quelle
2
Kannst du das etwas besser erklären? Wie berechnet dies das Alter?
Jonathan S. Fisher
1

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;
}
Andre P.
quelle
Dies ist ein wirklich niedlicher Vorschlag (wenn Sie Joda nicht verwenden und Java 8 nicht verwenden können), aber der Algorithmus ist etwas falsch, da Sie 0 sind, bis das gesamte erste Jahr vergangen ist. Sie müssen dem Datum also ein Jahr hinzufügen, bevor Sie die while-Schleife starten.
Dagmar
1

String dateofbirthhat das Geburtsdatum. und Format ist was auch immer (in der folgenden Zeile definiert):

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 ageStrwird die Jahre haben.

user1955658
quelle
1

Elegant, scheinbar korrekt , auf Zeitstempeldifferenzen basierende Variante der Yaron Ronen-Lösung.

Ich füge einen Komponententest hinzu, um zu beweisen, wann und warum er nicht korrekt ist . Es ist aufgrund (möglicherweise) unterschiedlicher Anzahl von Schalttagen (und Sekunden) in einem Zeitstempeldifferenz unmöglich. Die Diskrepanz sollte für diesen Algorithmus maximal + -1 Tag (und eine Sekunde) betragen, siehe test2 (), während die Yaron Ronen-Lösung auf einer vollständig konstanten Annahme von basierttimeDiff / MILLI_SECONDS_YEAR für einen 40-Jährigen 10 Tage abweichen kann, diese Variante jedoch auch falsch ist.

Dies ist schwierig, da diese verbesserte Variante unter Verwendung der Formel die diffAsCalendar.get(Calendar.YEAR) - 1970meiste Zeit korrekte Ergebnisse liefert, da die Anzahl der Schaltjahre im Durchschnitt zwischen zwei Daten 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));
    }
}
Espinosa
quelle
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
quelle
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
quelle
Ich bin mir nicht sicher, ob Sie diese wirklich getestet haben oder nicht, aber für andere hat diese Methode einen Fehler. Wenn das Heute derselbe Monat ist, in dem Ihr Geburtsdatum liegt, und heute <Geburtstag, wird immer noch das tatsächliche Alter + 1 angezeigt, z. B. wenn Ihr Geburtstag der 7. September 1986 und heute der 1. September 2013 ist, werden Ihnen stattdessen 27 angezeigt vom 26.
srahul07
2
Dies kann nicht zutreffen, da die Anzahl der Millisekunden pro Jahr NICHT KONSTANT ist. Schaltjahre haben einen Tag mehr, das sind viel mehr Millisekunden als andere. Für eine 40-jährige Person kann Ihr Algorithmus Geburtstag 9 - 10 Tage früher melden, als es wirklich ist! Es gibt auch Schaltsekunden.
Espinosa
0

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);
}
Akshay
quelle
0

Einfachster Weg ohne Bibliotheken:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;
lxknvlk
quelle
1
Dieser Code verwendet problematische alte Datums- / Uhrzeitklassen, die jetzt älter sind und durch die Klassen java.time ersetzt werden. Verwenden Sie stattdessen die in Java integrierten modernen Klassen : ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() ). Siehe richtige Antwort
Basil Bourque
DateUtilsist eine Bibliothek
Terraner
0

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();         
}
Mams
quelle
Alter im Jahr oder im Monat? Wie wäre es mit Baby im Monat?
Gumuruh
0

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

Ich hoffe, 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()
    }
ramana vv
quelle
Dies scheint ziemlich albern zu sein, wenn wir über die branchenführenden Java.time- Klassen verfügen .
Basil Bourque
OP-Anfragen in Java.
Terraner
-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
quelle
wie @sinuhepop bemerkte "Der DAY_OF_YEAR-Vergleich kann zu fehlerhaften Ergebnissen führen, wenn es um Schaltjahre geht"
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.
quelle
-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
quelle
Hinweis: Das Datumsformat lautet: JJJJ-MM-TT. Dies ist ein generischer Code, der in jdk7 getestet wird ...
Jhonie
1
Es wäre hilfreich, wenn Sie einige Kommentare abgeben oder erklären würden, wie dieser Code genau verwendet wird. Das einfache Codedumping wird normalerweise nicht empfohlen, und der Fragesteller versteht möglicherweise nicht, warum Sie sich entschieden haben, Ihre Methode auf diese Weise zu codieren.
Rayryeng
@rayryeng: Jhonie hat bereits Kommentare in den Code eingefügt. Das ist genug um zu verstehen. Bitte denken und lesen Sie, bevor Sie einen solchen Kommentar abgeben.
Akshay
@Akshay das war mir nicht klar. Im Nachhinein sah es so aus, als hätte er den Code abgeladen. Normalerweise lese ich keine Kommentare. Es wäre schön, wenn diese aus dem Körper entfernt und als Erklärung separat platziert würden. Das ist jedoch meine Präferenz und wir können uns darauf einigen, hier nicht zuzustimmen. Davon abgesehen habe ich vergessen, dass ich diesen Kommentar sogar so geschrieben habe, wie er vor fast zwei Jahren war.
Rayryeng
@rayryeng: Der Grund für diesen Kommentar war, dass das Schreiben negativer Kommentare die Leute davon abhält, ein so schönes Forum zu nutzen. Deshalb sollten wir sie durch positive Kommentare ermutigen. Bdw, nichts für ungut. Prost!!!
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
quelle
3
Vielen Dank für Ihre Teilnahme an StackOverflow. Ein paar Vorschläge für Sie. [A] Bitte fügen Sie Ihrer Antwort eine Diskussion bei. StackOverflow.com soll viel mehr als nur eine Code-Snippet-Sammlung sein. Beachten Sie beispielsweise, wie Ihr Code das neue Framework java.time verwendet, während die meisten anderen Antworten java.util.Date und Joda-Time verwenden. [B] Bitte kontrastieren Sie Ihre Antwort mit der ähnlichen Antwort von Meno Hochschild, die auch java.time verwendet. Erklären Sie, wie Ihre besser ist oder wie Sie das Problem aus einem anderen Blickwinkel betrachten. Oder ziehen Sie Ihre zurück, wenn nicht besser.
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
quelle