Java에서 다른 사람의 나이를 어떻게 계산합니까? = new Date().getTime() – getBirthDate().getTime();

Java 메소드에서 int로 몇 년을 반환하고 싶습니다. 내가 지금 가지고있는 것은 getBirthDate ()가 Date 객체 (생년월일 ;-)를 반환하는 위치입니다.

public int getAge() {
    long ageInMillis = new Date().getTime() - getBirthDate().getTime();

    Date age = new Date(ageInMillis);

    return age.getYear();
}

그러나 getYear ()가 더 이상 사용되지 않으므로 더 좋은 방법이 있는지 궁금합니다. 단위 테스트가 아직 (아직) 없기 때문에 이것이 올바르게 작동하는지조차 확실하지 않습니다.



답변

JDK 8은 이것을 쉽고 우아하게 만듭니다.

public class AgeCalculator {

    public static int calculateAge(LocalDate birthDate, LocalDate currentDate) {
        if ((birthDate != null) && (currentDate != null)) {
            return Period.between(birthDate, currentDate).getYears();
        } else {
            return 0;
        }
    }
}

사용법을 보여주는 JUnit 테스트 :

public class AgeCalculatorTest {

    @Test
    public void testCalculateAge_Success() {
        // setup
        LocalDate birthDate = LocalDate.of(1961, 5, 17);
        // exercise
        int actual = AgeCalculator.calculateAge(birthDate, LocalDate.of(2016, 7, 12));
        // assert
        Assert.assertEquals(55, actual);
    }
}

지금은 모두 JDK 8을 사용해야합니다. 모든 이전 버전은 지원 기간이 끝났습니다.


답변

날짜 / 시간 계산을 간소화 하는 Joda를 확인하십시오 (Joda는 새로운 표준 Java 날짜 / 시간 API의 기초이므로 곧 표준 API를 배우게됩니다).

편집 : Java 8은 매우 유사 하며 체크 아웃 할 가치가 있습니다.

예 :

LocalDate birthdate = new LocalDate (1970, 1, 20);
LocalDate now = new LocalDate();
Years age = Years.yearsBetween(birthdate, now);

원하는만큼 간단합니다. Java 8 이전의 것들은 (직접 알았 듯이) 다소 직관적이지 않습니다.


답변

Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(...);
if (dob.after(now)) {
  throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
int age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
  age--;
} else if (month1 == month2) {
  int day1 = now.get(Calendar.DAY_OF_MONTH);
  int day2 = dob.get(Calendar.DAY_OF_MONTH);
  if (day2 > day1) {
    age--;
  }
}
// age is now correct

답변

최신 답변 및 개요

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-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 등

비교를 위해 다양한 다른 답변을 참조하십시오. 결과 코드가 이국적인 경우에는 오류가 발생하기 쉽고 원래 질문이 너무 간단하다는 사실을 고려하면 너무 복잡하기 때문에이 오래된 클래스를 전혀 사용하지 않는 것이 좋습니다. 2015 년에는 더 나은 도서관이 있습니다.

d) Date4J 소개 :

제안 된 솔루션은 간단하지만 윤년이되면 실패 할 수 있습니다. 일의 평가만으로는 신뢰할 수 없습니다.

e) 내 라이브러리 Time4J :

이것은 Java-8 솔루션과 유사하게 작동합니다. 그냥 교체 LocalDatePlainDateChronoUnit.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

답변

/**
 * This Method is unit tested properly for very different cases ,
 * taking care of Leap Year days difference in a year,
 * and date cases month and Year boundary cases (12/31/1980, 01/01/1980 etc)
**/

public static int getAge(Date dateOfBirth) {

    Calendar today = Calendar.getInstance();
    Calendar birthDate = Calendar.getInstance();

    int age = 0;

    birthDate.setTime(dateOfBirth);
    if (birthDate.after(today)) {
        throw new IllegalArgumentException("Can't be born in the future");
    }

    age = today.get(Calendar.YEAR) - birthDate.get(Calendar.YEAR);

    // If birth date is greater than todays date (after 2 days adjustment of leap year) then decrement age one year   
    if ( (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3) ||
            (birthDate.get(Calendar.MONTH) > today.get(Calendar.MONTH ))){
        age--;

     // If birth date and todays date are of same month and birth day of month is greater than todays day of month then decrement age
    }else if ((birthDate.get(Calendar.MONTH) == today.get(Calendar.MONTH )) &&
              (birthDate.get(Calendar.DAY_OF_MONTH) > today.get(Calendar.DAY_OF_MONTH ))){
        age--;
    }

    return age;
}

답변

나는 단순히 일 년 상수 값으로 밀리 초를 사용하여 이점을 얻습니다.

Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);

답변

GWT를 사용하는 경우 java.util.Date 사용으로 제한됩니다. 날짜를 정수로 사용하지만 java.util.Date를 사용하는 메소드는 다음과 같습니다.

public int getAge(int year, int month, int day) {
    Date now = new Date();
    int nowMonth = now.getMonth()+1;
    int nowYear = now.getYear()+1900;
    int result = nowYear - year;

    if (month > nowMonth) {
        result--;
    }
    else if (month == nowMonth) {
        int nowDay = now.getDate();

        if (day > nowDay) {
            result--;
        }
    }
    return result;
}