Modern cevap ve genel bakış
a) Java-8 (java.time paketi)
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
İfadenin LocalDate.now()
, sistem saat dilimiyle (genellikle kullanıcılar tarafından göz ardı edilir) örtülü olarak ilişkili olduğunu unutmayın . Anlaşılır olması için, now(ZoneId.of("Europe/Paris"))
açık bir zaman dilimi belirten aşırı yüklenmiş yöntemi kullanmak daha iyidir (burada örnek olarak "Avrupa / Paris"). Sistem saat dilimi istenirse, kişisel tercihim, LocalDate.now(ZoneId.systemDefault())
sistem saat dilimi ile ilişkiyi daha net hale getirmek için yazmaktır . Bu daha fazla yazma çabasıdır ancak okumayı kolaylaştırır.
b) Joda-Time
Önerilen ve kabul edilen Joda-Time-çözümünün yukarıda gösterilen tarihler için farklı bir hesaplama sonucu verdiğini unutmayın (nadir bir durum), yani:
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
Bunu küçük bir hata olarak görüyorum, ancak Joda takımı bu garip davranış hakkında farklı bir görüşe sahip ve düzeltmek istemiyor (garip çünkü bitiş tarihi ayın başlangıç tarihi daha küçük olduğundan yıl olmalı bir tane daha az). Ayrıca bu kapalı konuya bakın .
c) java.util.Calendar vb.
Karşılaştırma için diğer cevaplara bakınız. Sonuçta ortaya çıkan kod hala bazı egzotik durumlarda ve / veya orijinal soru çok basit geliyor aslında göz önüne alındığında çok karmaşık hata eğilimli olduğundan bu eski sınıfları kullanmayı tavsiye etmem. 2015 yılında gerçekten daha iyi kütüphanelerimiz var.
d) Date4J Hakkında:
Önerilen çözüm basittir, ancak artık yıllar durumunda başarısız olacaktır. Sadece yılın gününü değerlendirmek güvenilir değildir.
e) Kendi kütüphanem Time4J :
Bu Java-8 çözümüne benzer şekilde çalışır. Sadece yerine LocalDate
göre PlainDate
ve ChronoUnit.YEARS
tarafından CalendarUnit.YEARS
. Ancak, "bugün" elde etmek için açık bir saat dilimi referansı gerekir.
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