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 LocalDate
nach PlainDate
und ChronoUnit.YEARS
nach 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