Câu trả lời hiện đại và tổng quan
a) Java-8 (java.time-gói)
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
Lưu ý rằng biểu thức LocalDate.now()
có liên quan ngầm đến múi giờ hệ thống (thường bị người dùng bỏ qua). Để rõ ràng, tốt hơn là sử dụng phương pháp quá tải now(ZoneId.of("Europe/Paris"))
chỉ định múi giờ rõ ràng (ví dụ "Châu Âu / Paris"). Nếu múi giờ hệ thống được yêu cầu thì sở thích cá nhân của tôi là viết LocalDate.now(ZoneId.systemDefault())
để làm cho mối quan hệ với múi giờ hệ thống rõ ràng hơn. Đây là nỗ lực viết nhiều hơn nhưng làm cho việc đọc dễ dàng hơn.
b) Thời gian Joda
Xin lưu ý rằng giải pháp Joda-Time được đề xuất và chấp nhận mang lại kết quả tính toán khác nhau cho các ngày được hiển thị ở trên (một trường hợp hiếm), cụ thể là:
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
Tôi coi đây là một lỗi nhỏ nhưng nhóm Joda có quan điểm khác về hành vi kỳ lạ này và không muốn sửa nó (kỳ lạ vì ngày kết thúc của ngày nhỏ hơn ngày bắt đầu nên năm nên một ít hơn). Xem thêm vấn đề kín này .
c) java.util.CalWiki, v.v.
Để so sánh xem các câu trả lời khác nhau. Tôi hoàn toàn không khuyên bạn nên sử dụng các lớp lỗi thời này bởi vì mã kết quả vẫn bị lỗi trong một số trường hợp kỳ lạ và / hoặc quá phức tạp khi xem xét thực tế rằng câu hỏi ban đầu nghe có vẻ đơn giản. Trong năm 2015 chúng tôi có thư viện thực sự tốt hơn.
d) Giới thiệu về Date4J:
Giải pháp đề xuất rất đơn giản nhưng đôi khi sẽ thất bại trong trường hợp năm nhuận. Chỉ đánh giá ngày trong năm là không đáng tin cậy.
e) Thư viện riêng của tôi Time4J :
Điều này hoạt động tương tự như giải pháp Java-8. Chỉ cần thay thế LocalDate
bởi PlainDate
và ChronoUnit.YEARS
bởi CalendarUnit.YEARS
. Tuy nhiên, nhận được "ngày hôm nay" đòi hỏi một tham chiếu múi giờ rõ ràng.
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