Jawaban dan gambaran umum modern
a) Java-8 (paket 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
Perhatikan bahwa ekspresi LocalDate.now()
secara implisit terkait dengan zona waktu sistem (yang sering diabaikan oleh pengguna). Untuk kejelasan itu umumnya lebih baik menggunakan metode kelebihan beban now(ZoneId.of("Europe/Paris"))
menentukan zona waktu eksplisit (contohnya "Eropa / Paris"). Jika zona waktu sistem diminta maka preferensi pribadi saya adalah menulis LocalDate.now(ZoneId.systemDefault())
untuk membuat hubungan dengan zona waktu sistem lebih jelas. Ini lebih merupakan upaya menulis tetapi membuat membaca lebih mudah.
b) Joda-Time
Harap perhatikan bahwa solusi Joda-Time yang diusulkan dan diterima menghasilkan hasil perhitungan yang berbeda untuk tanggal yang ditunjukkan di atas (kasus yang jarang terjadi), yaitu:
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
Saya menganggap ini sebagai bug kecil tetapi tim Joda memiliki pandangan yang berbeda tentang perilaku aneh ini dan tidak ingin memperbaikinya (aneh karena hari akhir bulan lebih kecil daripada tanggal mulai sehingga tahun seharusnya satu kurang). Lihat juga masalah tertutup ini .
c) java.util.Calendar dll.
Untuk perbandingan, lihat berbagai jawaban lainnya. Saya tidak akan merekomendasikan menggunakan kelas-kelas yang sudah usang ini sama sekali karena kode yang dihasilkan masih kesalahan dalam beberapa kasus eksotis dan / atau terlalu rumit mengingat fakta bahwa pertanyaan aslinya terdengar sangat sederhana. Pada tahun 2015 kami memiliki perpustakaan yang benar-benar lebih baik.
d) Tentang Date4J:
Solusi yang diusulkan sederhana tetapi kadang-kadang akan gagal jika tahun kabisat. Hanya mengevaluasi hari dalam setahun tidak dapat diandalkan.
e) Pustaka saya sendiri Time4J :
Ini berfungsi mirip dengan Java-8-solusi. Cukup ganti LocalDate
dengan PlainDate
dan ChronoUnit.YEARS
oleh CalendarUnit.YEARS
. Namun, mendapatkan "hari ini" memerlukan referensi zona waktu yang eksplisit.
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