Як обчислити чийсь вік на Java?


147

Я хочу повернути вік у роках як int у методі Java. Зараз у мене є таке, де getBirthDate () повертає об'єкт Date (з датою народження ;-)):

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

    Date age = new Date(ageInMillis);

    return age.getYear();
}

Але оскільки устарення getYear () застаріле, мені цікаво, чи є кращий спосіб зробити це? Я навіть не впевнений, що це працює правильно, оскільки у мене ще немає одиничних тестів.


Про це змінив свою думку: інше питання стосується лише наближення років між датами, а не справді правильного віку.
клетус

Враховуючи, що він повертає інт, чи можете ви уточнити, що ви маєте на увазі під «правильним» віком?
Брайан Агнеу

2
Date vs Calendar - це фундаментальна концепція, яку можна отримати, прочитавши документацію Java. Я не можу зрозуміти, чому це було б таким сильним вибором.
demongolem

@demongolem ??? Дата та календар легко зрозуміти ?! Ні, зовсім ні. Тут на мільйон запитань на цю тему на стеку переповнення. Проект Joda-Time створив одну з найпопулярніших бібліотек, щоб замінити ці клопітні класи часу. Пізніше спільнота Sun, Oracle та JCP прийняли 310 JSR ( java.time ), визнавши, що спадкові класи були безнадійно неадекватними. Для отримання додаткової інформації дивіться підручник Oracle .
Василь Бурк

Відповіді:


159

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. Усі попередні версії пройшли до кінця життя підтримки.


10
Порівняння DAY_OF_YEAR може призвести до помилкового результату при роботі з високосними роками.
sinuhepop

1
Змінна dateOfBirth має бути об'єктом Date. Як я можу створити об’єкт Дата з датою народження?
Ерік

Зважаючи на той факт, що нам вже 9 років, і якщо використовується Java 8, це має бути рішенням, яке слід використовувати.
nojevive

JDK 9 - поточна виробнича версія. Вірніше, ніж будь-коли.
duffymo

2
@SteveOh Я не згоден. Я б краще взагалі не приймав nulls, а натомість використовував Objects.requireNonNull.
MC Імператор

170

Ознайомтеся з Joda , який спрощує обчислення дати / часу (Joda також є основою нового стандартного apis дати / часу Java, тож ви дізнаєтесь, що скоро стане стандартним API).

EDIT: У Java 8 є щось дуже схоже, і його варто перевірити.

напр

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

що так просто, як ви могли хотіти. Попередньо Java 8 речі (як ви визначили) дещо неінтуїтивні.


2
@ HoàngLong: Від JavaDocs: "Цей клас представляє не день, а милісекундну мить опівночі. Якщо вам потрібен клас, який представляє цілий день, то інтервал або LocalDate може бути більш підходящим." Ми дійсно цього хочемо представити дату тут.
Джон Скіт

Якщо ви хочете зробити це так, як пропонує @JohnSkeet, це так: Years age = Years.yearsBet Between (новий LocalDate (getBirthDate ()), новий LocalDate ());
Флетч

Не знаю, чому я використовував DateMidnight, і зауважу, зараз він застарів. Тепер змінено на використання LocalDate
Brian Agnew


2
@IgorGanapolsky Дійсно основна відмінність полягає в тому, що конструктори використовують Joda-Time, тоді як Java-8 і ThreetenBP використовують статичні заводські методи. Для тонкої помилки в тому, як Joda-Time обчислює вік, будь ласка, подивіться на мою відповідь, де я дав огляд поведінки різних бібліотек.
Meno Hochschild

43
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

Так, календарний клас жахливий. На жаль, іноді мені доводиться користуватися на роботі: /. Дякую Клету, що опублікував це
Стів

1
Замініть календар.MONTH та Calendar.DAY_OF_MONTH на Calendar.DAY_OF_YEAR, і він буде принаймні трохи чистішим
Tobbbe

@Tobbbe Якщо ви народилися 1 березня у високосний рік, то ваш день народження - 1 березня наступного року, а не 2-го. DAY_OF_YEAR не працюватиме.
Airsource Ltd

42

Сучасна відповідь та огляд

a) Java-8 (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

Зауважте, що вираз LocalDate.now()неявно пов'язаний із часовим поясом системи (який користувачі часто не помічають). Для ясності, як правило, краще використовувати перевантажений метод із now(ZoneId.of("Europe/Paris"))зазначенням явного часового поясу (тут, наприклад, "Європа / Париж"). Якщо запитується часовий пояс системи, то моя особиста перевага - написати, LocalDate.now(ZoneId.systemDefault())щоб зробити відношення до часового поясу системи чіткішим. Це більше зусиль для письма, але полегшує читання.

б) Джода-час

Зауважте, що запропоноване та прийняте рішення Joda-Time дає різний результат обчислення для вказаних вище дат (рідкісний випадок), а саме:

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 має інший погляд на цю дивну поведінку і не хоче її виправляти (дивно, оскільки дата закінчення місяця менша, ніж дата початку, тому рік повинен бути один менше). Дивіться також це закрите питання .

в) java.util.Calendar тощо.

Для порівняння див. Різні відповіді. Я б не рекомендував використовувати ці застарілі класи взагалі, оскільки отриманий код все ще є помилковим у деяких екзотичних випадках та / або занадто складним, враховуючи той факт, що оригінальне запитання звучить так просто. У 2015 році ми маємо справді кращі бібліотеки.

г) Про Date4J:

Запропоноване рішення є простим, але іноді буде невдалим у разі високосних років. Просто оцінка дня року не є достовірною.

д) Моя власна бібліотека Time4J :

Це працює аналогічно Java-8-рішенню. Просто замініть 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

1
Дякую за версію Java 8! Це заощадило мені деякий час :) Тепер я просто повинен розібратися, як витягнути залишкові місяці. Наприклад 1 рік і 1 місяць. :)
thomas77

2
@ thomas77 Дякую за відповідь, комбіновані роки та місяці (а може бути й дні) можна виконати за допомогою `java.time.Period 'на Java-8. Якщо ви також хочете врахувати інші підрозділи, такі як години, Java-8 не пропонує рішення.
Мено Хоксшильд

Дякую ще раз (і за швидку відповідь) :)
thomas77

1
Пропоную вказати часовий пояс під час використання LocalDate.now. Якщо опущено поточний часовий пояс за замовчуванням JVM, неявно застосовується. Цей за замовчуванням може змінюватися між машинами / ОС / налаштуваннями, а також може в будь-який момент під час виконання будь-якого виклику коду setDefault. Я рекомендую бути конкретним, наприкладLocalDate.now( ZoneId.for( "America/Montreal" ) )
Василь Бурк

1
@GoCrafter_LP Так, ви можете застосувати ThreetenABP, що імітує Java-8, або Joda-Time-Android (від D. Lew) або мій lib Time4A для таких старих версій Android.
Мено Хохшильд

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;
}

2
Яка мета перевірки (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)? Це здається безглуздим із порівнянням місяця та дня місяця.
Джед Шааф

13

Я просто використовую постійні значення мілісекунди за рік:

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

2
Це не точна відповідь ... рік не 3.156e + 10, але 3.15576e + 10 (четвертий день!)
Maher Abuthraa

1
Це не працює, деякі роки є високосним і мають інше значення мсек
Грег Енніс

12

Якщо ви використовуєте 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;
}

5

Правильна відповідь за допомогою JodaTime :

public int getAge() {
    Years years = Years.yearsBetween(new LocalDate(getBirthDate()), new LocalDate());
    return years.getYears();
}

Ви можете навіть скоротити його в один рядок, якщо вам подобається. Я скопіював ідею з відповіді BrianAgnew , але я вважаю, що це правильніше, як ви бачите з коментарів там (і він точно відповідає на питання).


4

З бібліотекою date4j :

int age = today.getYear() - birthdate.getYear();
if(today.getDayOfYear() < birthdate.getDayOfYear()){
  age = age - 1; 
}

4

Це вдосконалена версія вищезгаданої ... враховуючи, що ви хочете, щоб вік був "int". тому що іноді не хочеться наповнювати свою програму купою бібліотек.

public int getAge(Date dateOfBirth) {
    int age = 0;
    Calendar born = Calendar.getInstance();
    Calendar now = Calendar.getInstance();
    if(dateOfBirth!= null) {
        now.setTime(new Date());
        born.setTime(dateOfBirth);  
        if(born.after(now)) {
            throw new IllegalArgumentException("Can't be born in the future");
        }
        age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);             
        if(now.get(Calendar.DAY_OF_YEAR) < born.get(Calendar.DAY_OF_YEAR))  {
            age-=1;
        }
    }  
    return age;
}

4

Це, мабуть, дивно, зауваживши, що вам не потрібно знати, скільки днів або місяців у році або скільки днів у цих місяцях, також вам не потрібно знати про високосні роки, стрибкові секунди чи будь-які інші цього матеріалу, використовуючи цей простий, 100% точний метод:

public static int age(Date birthday, Date date) {
    DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
    int d1 = Integer.parseInt(formatter.format(birthday));
    int d2 = Integer.parseInt(formatter.format(date));
    int age = (d2-d1)/10000;
    return age;
}

Я шукаю рішення для Java 6 і 5. Це просто, але точно.
Jj Tuibeo

3

Спробуйте скопіювати цей код у свій код, а потім скористайтеся методом для досягнення віку.

public static int getAge(Date birthday)
{
    GregorianCalendar today = new GregorianCalendar();
    GregorianCalendar bday = new GregorianCalendar();
    GregorianCalendar bdayThisYear = new GregorianCalendar();

    bday.setTime(birthday);
    bdayThisYear.setTime(birthday);
    bdayThisYear.set(Calendar.YEAR, today.get(Calendar.YEAR));

    int age = today.get(Calendar.YEAR) - bday.get(Calendar.YEAR);

    if(today.getTimeInMillis() < bdayThisYear.getTimeInMillis())
        age--;

    return age;
}

Відповідь лише на код не відлякує. Було б краще пояснити, чому цей код може вирішити питання щодо ОП.
рüффп

Насправді це не мозковий діяч, але оновиться лише для вирішення ваших проблем
Кевін

3

Я використовую цей фрагмент коду для обчислення віку, сподіваюся, це допомагає ..не бібліотеки використовуються

private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());

public static int calculateAge(String date) {

    int age = 0;
    try {
        Date date1 = dateFormat.parse(date);
        Calendar now = Calendar.getInstance();
        Calendar dob = Calendar.getInstance();
        dob.setTime(date1);
        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);
        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--;
            }
        }
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return age ;
}

2

Поля народження та ефект - це обидва поля дати:

Calendar bir = Calendar.getInstance();
bir.setTime(birth);
int birthNm = bir.get(Calendar.DAY_OF_YEAR);
int birthYear = bir.get(Calendar.YEAR);
Calendar eff = Calendar.getInstance();
eff.setTime(effect);

Це в основному модифікація рішення Дж. О без використання методів, що знецінюються. Я витратив досить багато часу, намагаючись змусити його код працювати над своїм кодом. Можливо, це заощадить інших цей час.


2
чи можете ви пояснити це трохи краще? як це обчислює вік?
Джонатан С. Фішер

1

Як щодо цього?

public Integer calculateAge(Date date) {
    if (date == null) {
        return null;
    }
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date);
    Calendar cal2 = Calendar.getInstance();
    int i = 0;
    while (cal1.before(cal2)) {
        cal1.add(Calendar.YEAR, 1);
        i += 1;
    }
    return i;
}

Це дуже мила пропозиція (коли ви не використовуєте Joda і не можете використовувати Java 8), але алгоритм трохи невірний, оскільки вам 0, поки не пройде весь перший рік. Тому вам потрібно додати рік до дати, перш ніж запускати цикл while.
Дагмар

1

String dateofbirthмає дату народження. і формат будь-який (визначений у наступному рядку):

org.joda.time.format.DateTimeFormatter formatter =  org.joda.time.format.DateTimeFormat.forPattern("mm/dd/yyyy");

Ось як форматувати:

org.joda.time.DateTime birthdateDate = formatter.parseDateTime(dateofbirth );
org.joda.time.DateMidnight birthdate = new         org.joda.time.DateMidnight(birthdateDate.getYear(), birthdateDate.getMonthOfYear(), birthdateDate.getDayOfMonth() );
org.joda.time.DateTime now = new org.joda.time.DateTime();
org.joda.time.Years age = org.joda.time.Years.yearsBetween(birthdate, now);
java.lang.String ageStr = java.lang.String.valueOf (age.getYears());

Змінні ageStrбудуть роки.


1

Елегантний, здавалося б, правильний варіант різниці часових позначок на основі рішення Ярона Ронена.

Я включаю тест одиниці, щоб довести, коли і чому це неправильно . Це неможливо через (можливо) різну кількість високосних днів (і секунд) в будь-якій різниці часових позначок. Розбіжність повинна бути максимум + -1 день (і одна секунда) для цього алгоритму, див. Тест2 (), тоді як рішення Ярона Ронена, засноване на повністю постійному припущенні, timeDiff / MILLI_SECONDS_YEARможе відрізнятися 10 днів для 40-річного віку, однак цей варіант також є невірним.

Це складно, оскільки цей покращений варіант, використовуючи формулу diffAsCalendar.get(Calendar.YEAR) - 1970, приносить правильні результати більшу частину часу, оскільки кількість високосних років у середньому однакова між двома датами.

/**
 * Compute person's age based on timestamp difference between birth date and given date
 * and prove it is INCORRECT approach.
 */
public class AgeUsingTimestamps {

public int getAge(Date today, Date dateOfBirth) {
    long diffAsLong = today.getTime() - dateOfBirth.getTime();
    Calendar diffAsCalendar = Calendar.getInstance();
    diffAsCalendar.setTimeInMillis(diffAsLong);
    return diffAsCalendar.get(Calendar.YEAR) - 1970; // base time where timestamp=0, precisely 1/1/1970 00:00:00 
}

    final static DateFormat df = new SimpleDateFormat("dd.MM.yyy HH:mm:ss");

    @Test
    public void test1() throws Exception {
        Date dateOfBirth = df.parse("10.1.2000 00:00:00");
        assertEquals(87, getAge(df.parse("08.1.2088 23:59:59"), dateOfBirth));
        assertEquals(87, getAge(df.parse("09.1.2088 23:59:59"), dateOfBirth));
        assertEquals(88, getAge(df.parse("10.1.2088 00:00:01"), dateOfBirth));
    }

    @Test
    public void test2() throws Exception {
        // between 2000 and 2021 was 6 leap days
        // but between 1970 (base time) and 1991 there was only 5 leap days
        // therefore age is switched one day earlier
            // See http://www.onlineconversion.com/leapyear.htm
        Date dateOfBirth = df.parse("10.1.2000 00:00:00");
        assertEquals(20, getAge(df.parse("08.1.2021 23:59:59"), dateOfBirth));
        assertEquals(20, getAge(df.parse("09.1.2021 23:59:59"), dateOfBirth)); // ERROR! returns incorrect age=21 here
        assertEquals(21, getAge(df.parse("10.1.2021 00:00:01"), dateOfBirth));
    }
}

1
public class CalculateAge { 

private int age;

private void setAge(int age){

    this.age=age;

}
public void calculateAge(Date date){

    Calendar calendar=Calendar.getInstance();

    Calendar calendarnow=Calendar.getInstance();    

    calendarnow.getTimeZone();

    calendar.setTime(date);

    int getmonth= calendar.get(calendar.MONTH);

    int getyears= calendar.get(calendar.YEAR);

    int currentmonth= calendarnow.get(calendarnow.MONTH);

    int currentyear= calendarnow.get(calendarnow.YEAR);

    int age = ((currentyear*12+currentmonth)-(getyears*12+getmonth))/12;

    setAge(age);
}
public int getAge(){

    return this.age;

}

0
/**
 * Compute from string date in the format of yyyy-MM-dd HH:mm:ss the age of a person.
 * @author Yaron Ronen
 * @date 04/06/2012  
 */
private int computeAge(String sDate)
{
    // Initial variables.
    Date dbDate = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");      

    // Parse sDate.
    try
    {
        dbDate = (Date)dateFormat.parse(sDate);
    }
    catch(ParseException e)
    {
        Log.e("MyApplication","Can not compute age from date:"+sDate,e);
        return ILLEGAL_DATE; // Const = -2
    }

    // Compute age.
    long timeDiff = System.currentTimeMillis() - dbDate.getTime();      
    int age = (int)(timeDiff / MILLI_SECONDS_YEAR);  // MILLI_SECONDS_YEAR = 31558464000L;

    return age; 
}

Не впевнений, ви справді перевіряли цей чи ні, але для інших цей метод має один недолік. якщо сьогодні той самий місяць, коли дата народження, а сьогодні <день народження, він все ще відображає фактичний вік + 1, тобто, наприклад, якщо ваш день народження - 7 вересня 1986 року, а сьогодні - 1 вересня 2013 року, він натомість покаже вам 27 від 26.
srahul07

2
Це не може бути правдою, оскільки кількість мілісекунд за рік НЕ СТАЄ. Випускні роки мають на один день більше, тобто набагато більше мілісекунд, ніж інші. Для 40-річної людини ваш алгоритм може повідомити про день народження на 9 - 10 днів раніше, ніж це насправді! Також є високосні секунди.
Еспіноса

0

Ось код Java для обчислення віку в році, місяці та днях.

public static AgeModel calculateAge(long birthDate) {
    int years = 0;
    int months = 0;
    int days = 0;

    if (birthDate != 0) {
        //create calendar object for birth day
        Calendar birthDay = Calendar.getInstance();
        birthDay.setTimeInMillis(birthDate);

        //create calendar object for current day
        Calendar now = Calendar.getInstance();
        Calendar current = Calendar.getInstance();
        //Get difference between years
        years = now.get(Calendar.YEAR) - birthDay.get(Calendar.YEAR);

        //get months
        int currMonth = now.get(Calendar.MONTH) + 1;
        int birthMonth = birthDay.get(Calendar.MONTH) + 1;

        //Get difference between months
        months = currMonth - birthMonth;

        //if month difference is in negative then reduce years by one and calculate the number of months.
        if (months < 0) {
            years--;
            months = 12 - birthMonth + currMonth;
        } else if (months == 0 && now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
            years--;
            months = 11;
        }

        //Calculate the days
        if (now.get(Calendar.DATE) > birthDay.get(Calendar.DATE))
            days = now.get(Calendar.DATE) - birthDay.get(Calendar.DATE);
        else if (now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
            int today = now.get(Calendar.DAY_OF_MONTH);
            now.add(Calendar.MONTH, -1);
            days = now.getActualMaximum(Calendar.DAY_OF_MONTH) - birthDay.get(Calendar.DAY_OF_MONTH) + today;
        } else {
            days = 0;
            if (months == 12) {
                years++;
                months = 0;
            }
        }
    }

    //Create new Age object
    return new AgeModel(days, months, years);
}

0

Найпростіший спосіб без бібліотек:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;

1
Цей код використовує тривожні старі класи дату, які тепер застаріли, заміщені класами java.time. Натомість використовуйте сучасні класи, вбудовані в Java : ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() ). Див. Правильну відповідь
Василь Бурк

DateUtilsє бібліотека
Terran

0

За допомогою Java 8 ми можемо обчислити вік людини за допомогою одного рядка коду:

public int calCAge(int year, int month,int days){             
    return LocalDate.now().minus(Period.of(year, month, days)).getYear();         
}

вік у році чи в місяці? як щодо дитини в місяць?
гумару

-1
public int getAge(Date dateOfBirth) 
{
    Calendar now = Calendar.getInstance();
    Calendar dob = Calendar.getInstance();

    dob.setTime(dateOfBirth);

    if (dob.after(now)) 
    {
        throw new IllegalArgumentException("Can't be born in the future");
    }

    int age = now.get(Calendar.YEAR) - dob.get(Calendar.YEAR);

    if (now.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR)) 
    {
        age--;
    }

    return age;
}

як @sinuhepop зауважив "Порівняння DAY_OF_YEAR може призвести до помилкового результату при роботі з високосними роками"
Кшиштоф Кот

-1
import java.io.*;

class AgeCalculator
{
    public static void main(String args[])
    {
        InputStreamReader ins=new InputStreamReader(System.in);
        BufferedReader hey=new BufferedReader(ins);

        try
        {
            System.out.println("Please enter your name: ");
            String name=hey.readLine();

            System.out.println("Please enter your birth date: ");
            String date=hey.readLine();

            System.out.println("please enter your birth month:");
            String month=hey.readLine();

            System.out.println("please enter your birth year:");
            String year=hey.readLine();

            System.out.println("please enter current year:");
            String cYear=hey.readLine();

            int bDate = Integer.parseInt(date);
            int bMonth = Integer.parseInt(month);
            int bYear = Integer.parseInt(year);
            int ccYear=Integer.parseInt(cYear);

            int age;

            age = ccYear-bYear;
            int totalMonth=12;
            int yourMonth=totalMonth-bMonth;

            System.out.println(" Hi " + name + " your are " + age + " years " + yourMonth + " months old ");
        }
        catch(IOException err)
        {
            System.out.println("");
        }
    }
}

-1
public int getAge(String birthdate, String today){
    // birthdate = "1986-02-22"
    // today = "2014-09-16"

    // String class has a split method for splitting a string
    // split(<delimiter>)
    // birth[0] = 1986 as string
    // birth[1] = 02 as string
    // birth[2] = 22 as string
    // now[0] = 2014 as string
    // now[1] = 09 as string
    // now[2] = 16 as string
    // **birth** and **now** arrays are automatically contains 3 elements 
    // split method here returns 3 elements because of yyyy-MM-dd value
    String birth[] = birthdate.split("-");
    String now[] = today.split("-");
    int age = 0;

    // let us convert string values into integer values
    // with the use of Integer.parseInt(<string>)
    int ybirth = Integer.parseInt(birth[0]);
    int mbirth = Integer.parseInt(birth[1]);
    int dbirth = Integer.parseInt(birth[2]);

    int ynow = Integer.parseInt(now[0]);
    int mnow = Integer.parseInt(now[1]);
    int dnow = Integer.parseInt(now[2]);

    if(ybirth < ynow){ // has age if birth year is lesser than current year
        age = ynow - ybirth; // let us get the interval of birth year and current year
        if(mbirth == mnow){ // when birth month comes, it's ok to have age = ynow - ybirth if
            if(dbirth > dnow) // birth day is coming. need to subtract 1 from age. not yet a bday
                age--;
        }else if(mbirth > mnow){ age--; } // birth month is comming. need to subtract 1 from age            
    }

    return age;
}

Примітка: Формат дати: yyyy-MM-dd. Це загальний код, який перевіряється в jdk7 ...
Jhonie

1
Це допоможе, якщо ви надали кілька коментарів або поясніть, як саме використовувати цей код. Просто демпінг коду зазвичай не рекомендується, і запитуючий питання може не зрозуміти ваш вибір, чому ви вирішили кодувати свій метод таким чином.
rayryeng

@rayryeng: Jhonie вже додав коментарі до коду. Цього достатньо, щоб зрозуміти. Будь ласка, подумайте та прочитайте, перш ніж давати такий коментар.
акшай

@Akshay це не було очевидно для мене. Заднім оглядом виглядало так, що він скидав код. Зазвичай я не читаю коментарів. Було б добре, якби їх вилучили з тіла і помістили окремо як пояснення. Це моє вподобання, і ми можемо погодитись не погодитися тут .... Втім, я забув, що навіть написав цей коментар, як це було майже два роки тому.
rayryeng

@rayryeng: Причиною цього коментаря було написання негативних коментарів, які відштовхують людей від використання такого приємного форуму. Отже, ми повинні їх заохочувати, даючи позитивні коментарі. Bdw, без образи. Ура !!!
акшай

-1
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.Period;

public class AgeCalculator1 {

    public static void main(String args[]) {
        LocalDate start = LocalDate.of(1970, 2, 23);
        LocalDate end = LocalDate.now(ZoneId.systemDefault());

        Period p = Period.between(start, end);
        //The output of the program is :
        //45 years 6 months and 6 days.
        System.out.print(p.getYears() + " year" + (p.getYears() > 1 ? "s " : " ") );
        System.out.print(p.getMonths() + " month" + (p.getMonths() > 1 ? "s and " : " and ") );
        System.out.print(p.getDays() + " day" + (p.getDays() > 1 ? "s.\n" : ".\n") );
    }//method main ends here.
}

3
Дякуємо за участь у StackOverflow. Пара пропозицій для вас. [A] Будь-ласка, включіть дещо обговорення у відповідь. StackOverflow.com призначений для набагато більше, ніж просто збірка фрагментів коду. Наприклад, зауважте, як ваш код використовує нову рамку java.time, тоді як більшість інших відповідей використовують java.util.Date та Joda-Time. [B] Будь ласка, порівняйте свою відповідь з аналогічною відповіддю Meno Hochschild, яка також використовує java.time. Поясніть, як вам краще, або атакуйте інший кут на проблему. Або відмовити свою, якщо не краще.
Василь Бурк

-1
public int getAge(Date birthDate) {
    Calendar a = Calendar.getInstance(Locale.US);
    a.setTime(date);
    Calendar b = Calendar.getInstance(Locale.US);
    int age = b.get(YEAR) - a.get(YEAR);
    if (a.get(MONTH) > b.get(MONTH) || (a.get(MONTH) == b.get(MONTH) && a.get(DATE) > b.get(DATE))) {
        age--;
    }
    return age;
}

-1

Я вдячний за всі правильні відповіді, але це відповідь Котліна на те саме питання

Сподіваюся, буде корисно розробникам kotlin

fun calculateAge(birthDate: Date): Int {
        val now = Date()
        val timeBetween = now.getTime() - birthDate.getTime();
        val yearsBetween = timeBetween / 3.15576e+10;
        return Math.floor(yearsBetween).toInt()
    }

Це здається досить нерозумним займатися такою математикою, коли у нас є провідні класи в галузі Java.time .
Василь Бурк

OP запити на Java.
Терран
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.