Рассчитать возраст с учетом даты рождения в формате ГГГГММДД - PullRequest
239 голосов
/ 30 октября 2010

Как рассчитать возраст в годах, учитывая дату рождения в формате ГГГГММДД?Возможно ли использовать функцию Date()?

Я ищу лучшее решение, чем то, которое я использую сейчас:

var dob = '19800810';
var year = Number(dob.substr(0, 4));
var month = Number(dob.substr(4, 2)) - 1;
var day = Number(dob.substr(6, 2));
var today = new Date();
var age = today.getFullYear() - year;
if (today.getMonth() < month || (today.getMonth() == month && today.getDate() < day)) {
  age--;
}
alert(age);

Ответы [ 40 ]

467 голосов
/ 17 августа 2011

Попробуйте это.

function getAge(dateString) {
    var today = new Date();
    var birthDate = new Date(dateString);
    var age = today.getFullYear() - birthDate.getFullYear();
    var m = today.getMonth() - birthDate.getMonth();
    if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
        age--;
    }
    return age;
}

Мне кажется, единственная вещь, которая выглядела грубо в вашем коде, была substr деталь.

Fiddle : http://jsfiddle.net/codeandcloud/n33RJ/

202 голосов
/ 24 февраля 2014

Я бы пошел на удобочитаемость:

function _calculateAge(birthday) { // birthday is a date
    var ageDifMs = Date.now() - birthday.getTime();
    var ageDate = new Date(ageDifMs); // miliseconds from epoch
    return Math.abs(ageDate.getUTCFullYear() - 1970);
}

Отказ от ответственности: Это также имеет проблемы с точностью, поэтому этому нельзя полностью доверять.Он может быть отключен на несколько часов, в некоторые годы или при переходе на летнее время (в зависимости от часового пояса).

Вместо этого я бы порекомендовал использовать для этого библиотеку, если точность очень важна.Также @Naveens post, вероятно, является наиболее точным, поскольку не зависит от времени суток.


Тесты: http://jsperf.com/birthday-calculation/15

70 голосов
/ 21 марта 2013

Важно: Этот ответ не дает 100% точного ответа, он выключен примерно на 10-20 часов в зависимости от даты.

Лучших решений не существует (во всяком случае, не в этих ответах). - Навин

Я, конечно, не смог устоять перед желанием принять вызов и сделать более быстрый и короткий калькулятор дня рождения, чем текущее принятое решение. Главное в моем решении - математика быстрая, поэтому вместо использования ветвления, а javascript модели даты предоставляет для вычисления решения, мы используем замечательную математику

Ответ выглядит следующим образом и работает на ~ 65% быстрее, чем у Навина, плюс он намного короче:

function calcAge(dateString) {
  var birthday = +new Date(dateString);
  return ~~((Date.now() - birthday) / (31557600000));
}

Магическое число: 31557600000 - это 24 *3600* 365.25 * 1000 Это длина года, длина года составляет 365 дней и 6 часов, что составляет 0,25 дня. В конце я получаю пол, который дает нам окончательный возраст.

Вот контрольные показатели: http://jsperf.com/birthday-calculation

Для поддержки формата данных OP вы можете заменить +new Date(dateString);
с +new Date(d.substr(0, 4), d.substr(4, 2)-1, d.substr(6, 2));

Если вы можете найти лучшее решение, пожалуйста, поделитесь! : -)

51 голосов
/ 06 мая 2014

с моментами:

/* The difference, in years, between NOW and 2012-05-07 */
moment().diff(moment('20120507', 'YYYYMMDD'), 'years')
13 голосов
/ 13 июня 2018

Чистый однострочный раствор ES6 с надписью:

const getAge = birthDate => Math.floor((new Date() - new Date(birthDate).getTime()) / 3.15576e+10)
// (today is 2018-06-13)
getAge('1994-06-14') // 23
getAge('1994-06-13') // 24

Использование года 365,25 дней (потому что високосные годы)

12 голосов
/ 30 октября 2010

Некоторое время назад я сделал функцию с этой целью:

function getAge(birthDate) {
  var now = new Date();

  function isLeap(year) {
    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
  }

  // days since the birthdate    
  var days = Math.floor((now.getTime() - birthDate.getTime())/1000/60/60/24);
  var age = 0;
  // iterate the years
  for (var y = birthDate.getFullYear(); y <= now.getFullYear(); y++){
    var daysInYear = isLeap(y) ? 366 : 365;
    if (days >= daysInYear){
      days -= daysInYear;
      age++;
      // increment the age only if there are available enough days for the year.
    }
  }
  return age;
}

Он принимает объект Date в качестве входных данных, поэтому вам нужно проанализировать форматированную строку даты 'YYYYMMDD':

var birthDateStr = '19840831',
    parts = birthDateStr.match(/(\d{4})(\d{2})(\d{2})/),
    dateObj = new Date(parts[1], parts[2]-1, parts[3]); // months 0-based!

getAge(dateObj); // 26
10 голосов
/ 12 декабря 2012

Вот мое решение, просто передайте разбираемую дату:

function getAge(birth) {
  ageMS = Date.parse(Date()) - Date.parse(birth);
  age = new Date();
  age.setTime(ageMS);
  ageYear = age.getFullYear() - 1970;

  return ageYear;

  // ageMonth = age.getMonth(); // Accurate calculation of the month part of the age
  // ageDay = age.getDate();    // Approximate calculation of the day part of the age
}
6 голосов
/ 12 февраля 2013

Альтернативное решение, потому что почему бы и нет:

function calculateAgeInYears (date) {
    var now = new Date();
    var current_year = now.getFullYear();
    var year_diff = current_year - date.getFullYear();
    var birthday_this_year = new Date(current_year, date.getMonth(), date.getDate());
    var has_had_birthday_this_year = (now >= birthday_this_year);

    return has_had_birthday_this_year
        ? year_diff
        : year_diff - 1;
}
5 голосов
/ 31 октября 2010
function age()
{
    var birthdate = $j('#birthDate').val(); // in   "mm/dd/yyyy" format
    var senddate = $j('#expireDate').val(); // in   "mm/dd/yyyy" format
    var x = birthdate.split("/");    
    var y = senddate.split("/");
    var bdays = x[1];
    var bmonths = x[0];
    var byear = x[2];
    //alert(bdays);
    var sdays = y[1];
    var smonths = y[0];
    var syear = y[2];
    //alert(sdays);

    if(sdays < bdays)
    {
        sdays = parseInt(sdays) + 30;
        smonths = parseInt(smonths) - 1;
        //alert(sdays);
        var fdays = sdays - bdays;
        //alert(fdays);
    }
    else{
        var fdays = sdays - bdays;
    }

    if(smonths < bmonths)
    {
        smonths = parseInt(smonths) + 12;
        syear = syear - 1;
        var fmonths = smonths - bmonths;
    }
    else
    {
        var fmonths = smonths - bmonths;
    }

    var fyear = syear - byear;
    document.getElementById('patientAge').value = fyear+' years '+fmonths+' months '+fdays+' days';
}
5 голосов
/ 30 октября 2010

Чтобы проверить, прошел ли день рождения или нет, я определяю вспомогательную функцию Date.prototype.getDoY, которая эффективно возвращает номер дня года. Остальное довольно очевидно.

Date.prototype.getDoY = function() {
    var onejan = new Date(this.getFullYear(), 0, 1);
    return Math.floor(((this - onejan) / 86400000) + 1);
};

function getAge(birthDate) {
    function isLeap(year) {
        return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
    }

    var now = new Date(),
        age = now.getFullYear() - birthDate.getFullYear(),
        doyNow = now.getDoY(),
        doyBirth = birthDate.getDoY();

    // normalize day-of-year in leap years
    if (isLeap(now.getFullYear()) && doyNow > 58 && doyBirth > 59)
        doyNow--;

    if (isLeap(birthDate.getFullYear()) && doyNow > 58 && doyBirth > 59)
        doyBirth--;

    if (doyNow <= doyBirth)
        age--;  // birthday not yet passed this year, so -1

    return age;
};

var myBirth = new Date(2001, 6, 4);
console.log(getAge(myBirth));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...