Как рассчитать чей-то возраст на Java?

Я хочу вернуть возраст в годах как int в методе Java. Теперь у меня есть следующее, где getBirthDate () возвращает объект Date (с датой рождения ;-)):

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

    Date age = new Date(ageInMillis);

    return age.getYear();
}

Но поскольку getYear () устарел, мне интересно, есть ли лучший способ сделать это? Я даже не уверен, что это работает правильно, поскольку у меня нет модульных тестов (пока).


person nojevive    schedule 12.07.2009    source источник
comment
Изменил свое мнение об этом: в другом вопросе есть только приблизительное количество лет между датами, а не действительно правильный возраст.   -  person cletus    schedule 12.07.2009
comment
Учитывая, что он возвращает int, можете ли вы пояснить, что вы подразумеваете под «правильным» возрастом?   -  person Brian Agnew    schedule 12.07.2009
comment
Дата и календарь - это фундаментальная концепция, которую можно почерпнуть из документации по Java. Я не могу понять, почему за это так проголосовали.   -  person demongolem    schedule 04.07.2012
comment
@demongolem ??? Дата и календарь легко понять ?! Нет, совсем нет. Здесь, в Stack Overflow, есть миллион вопросов по этой теме. В рамках проекта Joda-Time была создана одна из самых популярных библиотек, которая заменила эти неудобные классы времени и даты. Позже Sun, Oracle и сообщество JCP приняли JSR 310 ( java.time), признавая, что унаследованные классы были безнадежно неадекватными. Для получения дополнительной информации см. Руководство от Oracle .   -  person Basil Bourque    schedule 01.03.2018


Ответы (25)


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. Срок службы поддержки всех более ранних версий истек.

person duffymo    schedule 12.07.2009
comment
Сравнение DAY_OF_YEAR может привести к ошибочному результату при работе с високосными годами. - person sinuhepop; 18.04.2012
comment
Переменная dateOfBirth должна быть объектом Date. Как я могу создать объект Date с датой рождения? - person Erick; 03.09.2015
comment
Принимая во внимание тот факт, что прошло 9 лет, и в случае использования Java 8, это должно быть решение, которое следует использовать. - person nojevive; 10.04.2018
comment
JDK 9 - текущая производственная версия. Вернее, чем когда-либо. - person duffymo; 10.04.2018
comment
Я бы предпочел не return 0, а использовать Integer и null, чтобы обеспечить соответствие параметров допустимости значений NULL. - person Steve Oh; 06.09.2018
comment
К вашему сведению, некоторые люди платят за расширенные контракты на поддержку, чтобы продолжать использовать старые версии Java после общедоступной даты окончания срока службы, о которой вы упомянули. - person Basil Bourque; 11.01.2019
comment
Зачем тебе это нужно? Вы все еще используете Windows XP? Необходима определенная степень валюты. Исправления безопасности недоступны для старых версий. - person duffymo; 11.01.2019
comment
@SteveOh Я не согласен. Я бы предпочел вообще не принимать nulls, а вместо этого использовать Objects.requireNonNull. - person MC Emperor; 09.04.2019
comment
Если кому-то еще нужно преобразовать свою дату в LocalDate, например @Erick: stackoverflow.com/questions/21242110/ - person Sander; 18.10.2019
comment
как насчет более старого JDK вместо JDK 8? - person gumuruh; 28.05.2020
comment
Никто не должен использовать JDK старше 8. Я рекомендую. 11 или 13. - person duffymo; 28.05.2020

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

РЕДАКТИРОВАТЬ: Java 8 имеет что-то очень похожее, и его стоит проверить.

e.g.

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

это так просто, как вы могли бы пожелать. Материал до Java 8 (как вы определили) несколько не интуитивно понятен.

person Brian Agnew    schedule 12.07.2009
comment
@ HoàngLong: Из JavaDocs: Этот класс представляет не день, а мгновение миллисекунды в полночь. Если вам нужен класс, представляющий весь день, тогда могут быть более подходящими Interval или LocalDate. Мы действительно действительно хотим обозначить здесь дату. - person Jon Skeet; 08.03.2012
comment
Если вы хотите сделать это так, как предлагает @JohnSkeet, это будет примерно так: Years age = Years.yearsBetween (new LocalDate (getBirthDate ()), new LocalDate ()); - person Fletch; 24.09.2012
comment
Не знаю, почему я использовал DateMidnight, и теперь я отмечаю, что он устарел. Теперь изменено на использование LocalDate - person Brian Agnew; 06.11.2013
comment
это работает, но почему к возрасту добавляются буквы «P» и «Y»? т.е. печатает P45Y? - person Bor; 18.04.2015
comment
@Bor - joda-time.sourceforge .net / apidocs / org / joda / time / - person Brian Agnew; 19.04.2015
comment
@IgorGanapolsky Действительно, главное отличие: Joda-Time использует конструкторы, а Java-8 и ThreetenBP используют статические фабричные методы. Если есть небольшая ошибка в способе вычисления возраста Joda-Time, см. мой ответ, где я дал обзор поведение разных библиотек. - person Meno Hochschild; 20.08.2015
comment
Класс, представленный в Java 8, имеет имя Year not _2 _... очередь редактирования заполнена ... - person kiltek; 18.05.2017
comment
не могу найти Годовой идентификационный номер? - person gumuruh; 28.05.2020

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

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

c) 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
person Meno Hochschild    schedule 02.01.2015
comment
Спасибо за версию Java 8! Сэкономил мне время :) Теперь мне остается только понять, как извлечь оставшиеся месяцы. Например. 1 год и 1 месяц. :) - person thomas77; 12.02.2015
comment
@ thomas77 Спасибо за ответ, объединенные годы и месяцы (и, возможно, дни) можно сделать с помощью java.time.Period в Java-8. Если вы также хотите учитывать другие единицы, такие как часы, тогда Java-8 не предлагает решения. - person Meno Hochschild; 12.02.2015
comment
Еще раз спасибо (и за быстрый ответ) :) - person thomas77; 12.02.2015
comment
Я предлагаю указать часовой пояс при использовании LocalDate.now. Если этот параметр не указан, неявно применяется текущий часовой пояс JVM по умолчанию. Это значение по умолчанию может меняться между машинами / ОС / настройками, а также может в любой момент во время выполнения с помощью любого кода, вызывающего _ 2_. Я рекомендую быть конкретным, например LocalDate.now( ZoneId.for( "America/Montreal" ) ) - person Basil Bourque; 20.08.2015
comment
@BasilBourque Я скорректировал свой ответ, связанный с Java-8, чтобы включить ваш комментарий и посоветовать пользователям быть как можно более конкретными. - person Meno Hochschild; 20.08.2015
comment
старые версии Android не поддерживают Java 8 - person Martin; 09.06.2018
comment
@GoCrafter_LP Да, вы можете применить ThreetenABP, имитирующий Java-8, или Joda-Time-Android (от Д. Лью), или мою библиотеку Time4A для таких старых версий Android. - person Meno Hochschild; 09.06.2018

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

Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);
person Lou Morda    schedule 19.08.2015
comment
Это не точный ответ ... год - это не 3,156e + 10, а 3,15576e + 10 (четверть дня!) - person Maher Abuthraa; 09.08.2016
comment
Это не работает, некоторые годы являются високосными и имеют другое значение в миллисекундах. - person Greg Ennis; 08.05.2018

Если вы используете 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;
}
person Craigo    schedule 05.04.2011

Возможно, удивительно отметить, что вам не нужно знать, сколько дней или месяцев в году или сколько дней в этих месяцах, точно так же вам не нужно знать о високосных годах, високосных секундах и т. Д. всего этого, используя этот простой, на 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;
}
person weston    schedule 21.04.2015
comment
Я ищу решение для Java 6 и 5. Это просто, но точно. - person Jj Tuibeo; 13.05.2020
comment
Для безопасности NullPointerException добавьте if (birthday != null && date != null) и верните значение по умолчанию 0. - person stefan-dan; 17.03.2021
comment
Я бы предпочел, чтобы он разбился, чем иметь возраст по умолчанию 0 и двигаться дальше, чтобы вызвать ошибку в другом месте. Представьте: если бы я спросил вас, что родился ___, а сегодня 17 марта-2021, сколько мне лет? Вы бы сказали, что я не могу на это ответить, не вы 0 - person weston; 17.03.2021

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

Правильный ответ при использовании JodaTime:

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

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

person Fletch    schedule 24.09.2012

С помощью библиотеки date4j:

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

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

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;
}
person Kevin    schedule 15.03.2012
comment
Только код ответа не приветствуются. Было бы лучше объяснить, почему этот код может адресовать вопрос OP. - person рüффп; 13.10.2015
comment
На самом деле это и ежу понятно ... но будет обновлено, чтобы решить вашу проблему - person Kevin; 03.11.2015

Я использую этот фрагмент кода для расчета возраста. Надеюсь, это поможет ... библиотеки не использовались.

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 ;
}
person Ameen Maheen    schedule 27.12.2016

Поля рождение и эффект являются полями даты:

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

По сути, это модификация решения Джона О без использования устаревших методов. Я потратил довольно много времени, пытаясь заставить его код работать в моем коде. Может быть, тогда это спасет других.

person John B    schedule 12.07.2011
comment
Вы можете объяснить это немного лучше? как это вычислить возраст? - person Jonathan S. Fisher; 17.05.2013

Как насчет этого?

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;
}
person Andre P.    schedule 11.06.2012
comment
Это действительно симпатичное предложение (когда вы не используете Joda и не можете использовать Java 8), однако алгоритм немного неверен, потому что вы равняетесь нулю, пока не пройдет весь первый год. Поэтому вам нужно добавить год к дате, прежде чем запускать цикл while. - person Dagmar; 18.01.2018

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 будет иметь годы.

person user1955658    schedule 07.01.2013

Элегантный, на вид правильный вариант решения Ярона Ронена, основанный на разнице временных меток.

Я включаю модульный тест, чтобы доказать, когда и почему он неверен. Это невозможно из-за (возможно) разного количества високосных дней (и секунд) в любой разнице временных меток. Несоответствие должно быть макс + -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));
    }
}
person Espinosa    schedule 11.11.2013

Вот код 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);
}
person akshay    schedule 29.03.2016

Самый простой способ без библиотек:

    long today = new Date().getTime();
    long diff = today - birth;
    long age = diff / DateUtils.YEAR_IN_MILLIS;
person lxknvlk    schedule 21.07.2017
comment
В этом коде используются старые устаревшие классы даты и времени, которые теперь заменены классами java.time. Вместо этого используйте современные классы, встроенные в Java: ChronoUnit.YEARS.between( LocalDate.of( 1968 , Month.MARCH , 23 ) , LocalDate.now() ). См. правильный ответ - person Basil Bourque; 21.07.2017
comment
DateUtils - это библиотека - person Terran; 15.10.2019

В Java 8 мы можем вычислить возраст человека с помощью одной строчки кода:

public int calCAge(int year, int month,int days){             
    return LocalDate.now().minus(Period.of(year, month, days)).getYear();         
}
person Mam's    schedule 09.04.2018
comment
возраст в год или в месяц? как насчет ребенка через месяц? - person gumuruh; 28.05.2020

Я ценю все правильные ответы, но это ответ котлина на тот же вопрос

Надеюсь, это будет полезно разработчикам 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()
    }
person ramana vv    schedule 30.06.2018
comment
Кажется довольно глупым заниматься такой математикой, когда в нашем распоряжении есть лучшие в отрасли классы java.time. - person Basil Bourque; 30.06.2018
comment
Запросы OP в Java. - person Terran; 15.10.2019

person    schedule
comment
Ага, календарный класс ужасен. К сожалению, на работе иногда приходится пользоваться: /. Спасибо Клетусу за публикацию этого - person Steve; 30.09.2016
comment
Замените Calendar.MONTH и Calendar.DAY_OF_MONTH на Calendar.DAY_OF_YEAR, и он будет, по крайней мере, немного чище - person Tobbbe; 30.05.2017
comment
@Tobbbe Если вы родились 1 марта високосного года, то ваш день рождения будет 1 марта следующего года, а не 2. DAY_OF_YEAR не сработает. - person Airsource Ltd; 27.02.2020

person    schedule
comment
Какова цель проверки (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3)? Это кажется бессмысленным при существовании сравнения месяца и дня месяца. - person Jed Schaaf; 03.03.2016

person    schedule
comment
Не уверен, действительно ли вы тестировали этот метод или нет, но для других этот метод имеет один недостаток. если сегодня тот же месяц, что и ваша дата рождения, а сегодня ‹день рождения, он все равно показывает фактический возраст + 1, то есть, например, если ваш день рождения 7 сентября 1986 года, а сегодня 1 сентября 2013 года, вместо этого будет показано 27 из 26. - person Rahul Shelke; 13.06.2013
comment
Это не может быть правдой, поскольку количество миллисекунд в году НЕ ПОСТОЯННО. В високосных годах на один день больше, то есть на миллисекунды больше, чем в других. Для 40-летнего человека ваш алгоритм может сообщить день рождения на 9-10 дней раньше, чем он есть на самом деле! Есть также дополнительные секунды. - person Espinosa; 11.11.2013

person    schedule
comment
как заметил @sinuhepop. Сравнение DAY_OF_YEAR может привести к ошибочному результату при работе с високосными годами. - person Krzysztof Kot; 23.04.2012

person    schedule
comment
Примечание. Формат даты: гггг-ММ-дд. Это общий код, протестированный в jdk7 ... - person Jhonie; 16.09.2014
comment
Было бы полезно, если бы вы предоставили несколько комментариев или объяснили, как именно использовать этот код. Простой сброс кода обычно не приветствуется, и задающий вопрос может не понять ваш выбор, почему вы решили закодировать свой метод таким образом. - person rayryeng; 16.09.2014
comment
@rayryeng: Джони уже добавил комментарии в код. Этого достаточно, чтобы понять. Пожалуйста, подумайте и прочтите, прежде чем давать такой комментарий. - person akshay; 30.03.2016
comment
@ Акшай, для меня это было неочевидно. Оглядываясь назад, казалось, что он сбросил код. Обычно я не читаю комментарии. Было бы неплохо, если бы они были извлечены из тела и помещены отдельно в качестве объяснения. Это мое предпочтение, и мы можем согласиться не соглашаться здесь .... При этом я забыл, что даже написал этот комментарий, как это было почти два года назад. - person rayryeng; 30.03.2016
comment
@rayryeng: Причина этого комментария заключалась в том, что негативные комментарии мешают людям использовать такой хороший форум. Так что мы должны поощрять их, давая положительные комментарии. Бдв, без обид. Ваше здоровье!!! - person akshay; 30.03.2016
comment
@Akshay, и я согласен с этим. Этот комментарий был сделан, когда я был еще новым пользователем :). Ура и спасибо за ваш отзыв. - person rayryeng; 30.03.2016

person    schedule
comment
Спасибо за участие в StackOverflow. Пара предложений для вас. [A] Пожалуйста, включите обсуждение в свой ответ. StackOverflow.com - это нечто большее, чем просто коллекция фрагментов кода. Например, обратите внимание, как ваш код использует новую структуру java.time, в то время как большинство других ответов используют java.util.Date и Joda-Time. [B] Сравните свой ответ с аналогичным ответом Мено Хохшильда, который также использует java.time. Объясните, чем ваша лучше, или взгляните на проблему под другим углом. Или откажитесь от своего, если не лучше. - person Basil Bourque; 30.08.2015