คำตอบและภาพรวมที่ทันสมัย
a) Java-8 (java.time-package)
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
โปรดทราบว่าการแสดงออกLocalDate.now()
ที่เกี่ยวข้องโดยปริยายกับเขตเวลาของระบบ (ซึ่งมักจะมองข้ามโดยผู้ใช้) เพื่อความชัดเจนจะดีกว่าหากใช้วิธีโอเวอร์โหลดที่now(ZoneId.of("Europe/Paris"))
ระบุเขตเวลาที่ชัดเจน (ที่นี่ "ยุโรป / ปารีส" เป็นตัวอย่าง) หากมีการร้องขอเขตเวลาของระบบการตั้งค่าส่วนตัวของฉันคือการเขียนLocalDate.now(ZoneId.systemDefault())
เพื่อให้ความสัมพันธ์กับเขตเวลาของระบบชัดเจนขึ้น นี่คือความพยายามในการเขียนที่มากขึ้น แต่ทำให้การอ่านง่ายขึ้น
b) Joda-Time
โปรดทราบว่าวิธีการแก้ปัญหาที่เสนอและยอมรับ Joda-Time-solution ให้ผลลัพธ์การคำนวณที่แตกต่างกันสำหรับวันที่แสดงข้างต้น (กรณีที่หายาก) คือ:
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
ฉันคิดว่านี่เป็นข้อผิดพลาดเล็ก ๆ แต่ทีม Joda มีมุมมองที่แตกต่างกันเกี่ยวกับพฤติกรรมแปลก ๆ นี้และไม่ต้องการแก้ไข (แปลกเพราะวันสิ้นเดือนมีขนาดเล็กกว่าวันที่เริ่มต้นดังนั้นปีควรจะเป็น หนึ่งน้อยกว่า) ดูเพิ่มเติมที่ปิดนี้ปัญหา
c) java.util.Calendar เป็นต้น
สำหรับการเปรียบเทียบดูคำตอบอื่น ๆ อีกมากมาย ฉันจะไม่แนะนำให้ใช้คลาสที่ล้าสมัยเหล่านี้เลยเพราะรหัสผลลัพธ์ยังคงเป็น errorprone ในบางกรณีที่แปลกใหม่และ / หรือวิธีที่ซับซ้อนเกินไปเมื่อพิจารณาจากข้อเท็จจริงที่ว่าคำถามดั้งเดิมฟังดูง่ายมาก ในปี 2558 เรามีห้องสมุดที่ดีกว่าจริงๆ
d) เกี่ยวกับ Date4J:
วิธีแก้ปัญหาที่เสนอนั้นง่าย แต่บางครั้งก็อาจล้มเหลวในกรณีของปีอธิกสุรทิน เพียงแค่การประเมินวันของปีไม่น่าเชื่อถือ
e) ห้องสมุดของฉัน Time4J :
สิ่งนี้ทำงานคล้ายกับ Java-8-solution เพียงแค่เปลี่ยนLocalDate
จากPlainDate
และโดยChronoUnit.YEARS
CalendarUnit.YEARS
อย่างไรก็ตามการได้รับ "วันนี้" ต้องมีการอ้างอิงเขตเวลาอย่างชัดเจน
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