Как рассчитать чей-то возраст на 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 () устарела, мне интересно, есть ли лучший способ сделать это? Я даже не уверен, что это работает правильно, так как у меня нет модульных тестов (пока).


Передумал по этому поводу: другой вопрос имеет приблизительное количество лет между датами, а не действительно правильный возраст.
Клет

Учитывая, что он возвращает int, вы можете уточнить, что вы подразумеваете под «правильным» возрастом?
Брайан Агнью

2
Дата против Календаря - фундаментальная концепция, которую можно почерпнуть из чтения документации по Java. Я не могу понять, почему за это так много проголосовало.
демонголем

@demongolem ??? Дата и календарь легко понять ?! Нет, совсем нет. Здесь есть множество вопросов по теме переполнения стека. В рамках проекта Joda-Time была создана одна из самых популярных библиотек, которая заменила эти хлопотные уроки даты и времени. Позже Sun, Oracle и сообщество JCP приняли JSR 310 ( 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. Как я могу создать объект Date с датой рождения?
Эрик

Ввиду того, что нам уже 9 лет, и в случае использования Java 8 это решение должно быть использовано.
августа

JDK 9 является текущей производственной версией. Вернее, чем когда-либо.
duffymo

2
@ SteveOh Я не согласен. Я бы предпочел не принимать nulls вообще, а вместо этого использовать Objects.requireNonNull.
MC Emperor

170

Посмотрите на Joda , которая упрощает вычисления даты / времени (Joda также является основой нового стандартного API даты / времени Java, поэтому вы изучите API , который скоро станет стандартом).

РЕДАКТИРОВАТЬ: 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: «Этот класс представляет не день, а миллисекундный момент в полночь. Если вам нужен класс, представляющий весь день, то Interval или LocalDate могут быть более подходящими». Мы действительно этого хотим представить дату здесь.
Джон Скит

Если вы хотите сделать это так, как предлагает @JohnSkeet, это выглядит так: Years age = Years.yearsBetween (new LocalDate (getBirthDate ()), new LocalDate ());
Флетч

Не знаю, почему я использовал DateMidnight, и я отмечаю, что это устарело. Изменено использование LocalDate
Брайан Агнью


2
@IgorGanapolsky Действительно, главное отличие заключается в том, что Joda-Time использует конструкторы, а Java-8 и ThreetenBP используют статические фабричные методы. Чтобы увидеть небольшую ошибку в том, как Joda-Time рассчитывает возраст, пожалуйста, посмотрите на мой ответ, где я дал обзор поведения различных библиотек.
Мено Хохшильд

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

Да, класс календаря ужасен. К сожалению, на работе иногда приходится этим пользоваться: /. Спасибо Cletus за публикацию этого сообщения
Стив

1
Замените Calendar.MONTH и Calendar.DAY_OF_MONTH на Calendar.DAY_OF_YEAR, и это будет, по крайней мере, немного чище
Тобббе

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

42

Современный ответ и обзор

а) 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 не предлагает решения.
Мено Хохшильд


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 (четверть дня!)
Махер Абутраа

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

Вы можете даже сократить его в одну строку, если хотите. Я скопировал идею из ответа Брайана Агнью , но я считаю, что это более правильно, как вы видите из комментариев (и это точно отвечает на вопрос).


4

С библиотекой date4j :

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

4

Это улучшенная версия вышеупомянутой ... учитывая, что вы хотите, чтобы age был 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;
}

Код только ответ не приветствуется. Было бы лучше объяснить, почему этот код может решить вопрос OP.
рюффп

Это на самом деле не просто ... но будет обновлять только для решения вашей проблемы
Кевин

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

Элегантный, казалось бы, правильный вариант решения Yaron Ronen, основанный на разнице во времени.

Я включаю модульный тест, чтобы доказать, когда и почему это не правильно . Это невозможно из-за (возможно) разного количества високосных дней (и секунд) при любой разнице во времени. Расхождение должно составлять максимум + -1 день (и одна секунда) для этого алгоритма, см. Test2 (), тогда как решение Ярона Ронена, основанное на полностью постоянном предположении, 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это библиотека
терран

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

Примечание. Формат даты: гггг-мм-дд. Это общий код, который тестируется в jdk7 ...
Jhonie

1
Было бы полезно, если бы вы предоставили некоторые комментарии или объяснили, как именно использовать этот код. Просто дамп кода обычно не рекомендуется, и задающий вопрос может не понимать ваш выбор, почему вы решили так закодировать свой метод.
Rayryeng

@rayryeng: Джони уже добавил комментарии в коде. Этого достаточно, чтобы понять. Пожалуйста, подумайте и прочитайте, прежде чем давать такой комментарий.
Акшай

@ Акшай, это не было очевидно для меня. Оглядываясь назад, он выглядел так, как будто он выбросил код. Я обычно не читаю комментарии. Было бы хорошо, если бы они были удалены из тела и помещены отдельно в качестве объяснения. Это мое предпочтение, хотя, и мы можем согласиться не соглашаться здесь ... При этом я забыл, что даже написал этот комментарий, как это было почти два года назад.
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] Пожалуйста, сопоставьте ваш ответ с аналогичным ответом Мено Хохшильда, который также использует 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 ответ на тот же вопрос

Я надеюсь, будет полезно для разработчиков 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.
Terran
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.