PHP рассчитать возраст

160

Я ищу способ рассчитать возраст человека, учитывая его DOB в формате дд / мм / гггг.

Я использовал следующую функцию, которая работала отлично в течение нескольких месяцев, пока какой-то сбой не привел к тому, что цикл while никогда не заканчивался и не останавливал весь сайт. Так как почти 100 000 DOB выполняют эту функцию несколько раз в день, трудно определить причину этого.

У кого-нибудь есть более надежный способ подсчета возраста?

//replace / with - so strtotime works
$dob = strtotime(str_replace("/","-",$birthdayDate));       
$tdate = time();

$age = 0;
while( $tdate > $dob = strtotime('+1 year', $dob))
{
    ++$age;
}
return $age;

РЕДАКТИРОВАТЬ: эта функция иногда работает нормально, но возвращает «40» для DOB от 14.09.1986

return floor((time() - strtotime($birthdayDate))/31556926);
Stef
источник

Ответы:

193

Это отлично работает.

<?php
  //date in mm/dd/yyyy format; or it can be in other formats as well
  $birthDate = "12/17/1983";
  //explode the date to get month, day and year
  $birthDate = explode("/", $birthDate);
  //get age from date or birthdate
  $age = (date("md", date("U", mktime(0, 0, 0, $birthDate[0], $birthDate[1], $birthDate[2]))) > date("md")
    ? ((date("Y") - $birthDate[2]) - 1)
    : (date("Y") - $birthDate[2]));
  echo "Age is:" . $age;
?>
Судхир Бастакоти
источник
1
Согласитесь, когда-нибудь для этого формата нам нужно использовать mktime(). Кажется, php просчитался strtotime()с этим форматом.
GusDeCooL
30
PHP strtotimeпрекрасно понимает форматы дат, вам не нужно беспокоиться: Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed. php.net/manual/en/function.strtotime.php
s3v3n
Эта функция действительно дороже, чем другие решения. Это происходит из-за чрезмерного использования функции date ().
Jarzon
Хорошая проставленная дата. Спасибо
Рок Мехос
172
$tz  = new DateTimeZone('Europe/Brussels');
$age = DateTime::createFromFormat('d/m/Y', '12/02/1973', $tz)
     ->diff(new DateTime('now', $tz))
     ->y;

Начиная с PHP 5.3.0, вы можете использовать эту удобную функцию, DateTime::createFromFormatчтобы убедиться, что ваша дата не будет ошибочно принята за m/d/Yформат и DateIntervalкласс (через DateTime::diff), чтобы получить количество лет между текущей и целевой датой.

Salathe
источник
1
Выглядит многообещающе, но, к сожалению, большинство серверных хостингов в моей стране все еще используют PHP 5.2.x :(
GusDeCooL
3
Действительно ли нужен часовой пояс?
Андре Шалелла
127
 $date = new DateTime($bithdayDate);
 $now = new DateTime();
 $interval = $now->diff($date);
 return $interval->y;
Wernight
источник
Я пытался использовать DateTime () раньше, но это замораживает скрипт. В моих журналах я вижу предупреждение PHP: date (): небезопасно полагаться на настройки часового пояса системы, даже когда я добавляю date_default_timezone_set ('Europe / Brussels');
Стеф
1
Вы уверены, что удалили # перед этой строкой? Вы должны установить это в PHP.ini
Wernight
Обычно безопасно игнорировать это предупреждение (особенно в этом случае).
Wernight
96

Я использую дату / время для этого:

$age = date_diff(date_create($bdate), date_create('now'))->y;
Андрей Корчак
источник
Вы можете использовать что-то вроде этого для форматов дат в британском стиле: $ age = date_diff (date_create (str_replace ('/', '.', $ Bdate)), date_create ('now')) -> y; из-за stackoverflow.com/questions/4163641/…
Ричард
1
Самое простое решение, только одна строка. Работает только на PHP 5.3+
Rhaymand Tatlonghari
60

Простой метод расчета возраста от доб:

$_age = floor((time() - strtotime('1986-09-16')) / 31556926);

31556926 количество секунд в году.

Майк
источник
16
чрезмерное использование функций ...$_age = floor((time() - strtotime('1986-09-16')) / 31556926);
Mavelo
4
Лучшее решение ... 1 вкладыш, простой и неиспользуемый: mktime
Timmy
1
@RobertM. Это так плохо в этом случае? Я не думаю, что эти функции
настолько
1
@ Dewan159 посмотрите историю изменений ... была изменена в соответствии с моим решением;)
Mavelo
4
Как насчет високосных секунд?
Ксимка
17

// Возрастной калькулятор

function getAge($dob,$condate){ 
    $birthdate = new DateTime(date("Y-m-d",  strtotime(implode('-', array_reverse(explode('/', $dob))))));
    $today= new DateTime(date("Y-m-d",  strtotime(implode('-', array_reverse(explode('/', $condate))))));           
    $age = $birthdate->diff($today)->y;

    return $age;
}

$dob='06/06/1996'; //date of Birth
$condate='07/02/16'; //Certain fix Date of Age 
echo getAge($dob,$condate);
matinict
источник
5
Лучшее современное решение 2016.
AlexioVay
14

Я считаю, что это работает и просто.

Вычтите из 1970, потому что strtotime вычисляет время из 1970-01-01 ( http://php.net/manual/en/function.strtotime.php )

function getAge($date) {
    return intval(date('Y', time() - strtotime($date))) - 1970;
}

Полученные результаты:

Current Time: 2015-10-22 10:04:23

getAge('2005-10-22') // => 10
getAge('1997-10-22 10:06:52') // one 1s before  => 17
getAge('1997-10-22 10:06:50') // one 1s after => 18
getAge('1985-02-04') // => 30
getAge('1920-02-29') // => 95
Трэвис Марк Чонг
источник
Почти верно ... strtotime () вычисляет время с 1969-12-31 18:00:00
феникс
8

Если вы хотите рассчитать возраст использования dob, вы также можете использовать эту функцию. Он использует объект DateTime.

function calcutateAge($dob){

        $dob = date("Y-m-d",strtotime($dob));

        $dobObject = new DateTime($dob);
        $nowObject = new DateTime();

        $diff = $dobObject->diff($nowObject);

        return $diff->y;

}
hmoyat
источник
8

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

Я провел 100-летнее сравнение трех наиболее популярных типов возрастных функций, которые я мог найти для PHP, и опубликовал результаты (а также функции) в своем блоге. .

Как вы можете видеть здесь , все 3 funcs хорошо преформы только с небольшой разницей на 2 - е функции. Мое предложение, основанное на моих результатах, состоит в том, чтобы использовать 3-ю функцию, если вы не хотите делать что-то конкретное в день рождения человека, и в этом случае 1-я функция предоставляет простой способ сделать именно это.

Обнаружена небольшая проблема с тестом, а другая проблема со 2-м методом! Обновление скоро появится в блоге! На данный момент, я бы принял к сведению, что 2-й метод по-прежнему самый популярный, который я нахожу в Интернете, и, тем не менее, он все еще является наиболее неточным!

Мои предложения после моего 100-летнего обзора:

Если вы хотите что-то более вытянутое, чтобы вы могли включать такие случаи, как дни рождения и такие:

function getAge($date) { // Y-m-d format
    $now = explode("-", date('Y-m-d'));
    $dob = explode("-", $date);
    $dif = $now[0] - $dob[0];
    if ($dob[1] > $now[1]) { // birthday month has not hit this year
        $dif -= 1;
    }
    elseif ($dob[1] == $now[1]) { // birthday month is this month, check day
        if ($dob[2] > $now[2]) {
            $dif -= 1;
        }
        elseif ($dob[2] == $now[2]) { // Happy Birthday!
            $dif = $dif." Happy Birthday!";
        };
    };
    return $dif;
}

getAge('1980-02-29');

Но если вы просто хотите узнать возраст и не более того:

function getAge($date) { // Y-m-d format
    return intval(substr(date('Ymd') - date('Ymd', strtotime($date)), 0, -4));
}

getAge('1980-02-29');

Смотрите БЛОГ


Ключевое примечание о strtotimeметоде:

Note:

Dates in the m/d/y or d-m-y formats are disambiguated by looking at the 
separator between the various components: if the separator is a slash (/), 
then the American m/d/y is assumed; whereas if the separator is a dash (-) 
or a dot (.), then the European d-m-y format is assumed. If, however, the 
year is given in a two digit format and the separator is a dash (-, the date 
string is parsed as y-m-d.

To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates or 
DateTime::createFromFormat() when possible.
SpYk3HH
источник
8

Вы можете использовать Carbonбиблиотеку , которая является расширением API для DateTime.

Ты можешь:

function calculate_age($date) {
    $date = new \Carbon\Carbon($date);
    return (int) $date->diffInYears();
}

или:

$age = (new \Carbon\Carbon($date))->age;
Броши
источник
1
Это более чистое решение, но оно требует внешней библиотеки, которая не может быть лучшей для каждого проекта
Stef
1
углерод предлагает магическое свойство age, которое делает diffInYears. Таким образом, вы можете написать:(new \Carbon\Carbon($date))->age
k0pernikus
4

Если вам не нужна большая точность, просто количество лет, вы можете использовать приведенный ниже код ...

 print floor((time() - strtotime("1971-11-20")) / (60*60*24*365));

Вам нужно только поместить это в функцию и заменить дату «1971-11-20» на переменную.

Обратите внимание, что точность приведенного выше кода невелика из-за високосных лет, т.е. примерно каждые 4 года дни 366 вместо 365. Выражение 60 * 60 * 24 * 365 вычисляет количество секунд в одном году - вы можете замените его на 31536000.

Другая важная вещь заключается в том, что из-за использования метки времени UNIX возникает проблема как 1901 года, так и 2038 года, что означает, что приведенное выше выражение не будет корректно работать для дат до 1901 года и после 2038 года.

Если вы можете жить с ограничениями, упомянутыми выше, этот код должен работать для вас.

Невен Боянов
источник
что произойдет в 2038 году "любая система" потерпит крах, если использует time ()?
Мигель
3
//replace / with - so strtotime works
$dob = strtotime(str_replace("/","-",$birthdayDate));       
$tdate = time();
return date('Y', $tdate) - date('Y', $dob);
Сергей Еремин
источник
1
Не работает Ваша функция будет указывать на то, что кто-то, родившийся 1 сентября 1990 года, того же возраста, что и человек, родившийся 1 октября 1990 года, - для них обоих будет рассчитано (2010 - 1990 гг.) = 20.
PaulJWilliams
какая точность возраста вам нужна? месяц? день?
Сергей Еремин
3
  function dob ($birthday){
    list($day,$month,$year) = explode("/",$birthday);
    $year_diff  = date("Y") - $year;
    $month_diff = date("m") - $month;
    $day_diff   = date("d") - $day;
    if ($day_diff < 0 || $month_diff < 0)
      $year_diff--;
    return $year_diff;
  }
CristiC
источник
Кажется, хорошо в некоторые даты, но для других он ничего не возвращает, предположительно, если IF не выполняется?
Стеф
3

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

/*
* Get age from dob
* @param        dob      string       The dob to validate in mysql format (yyyy-mm-dd)
* @return            integer      The age in years as of the current date
*/
function getAge($dob) {
    //calculate years of age (input string: YYYY-MM-DD)
    list($year, $month, $day) = explode("-", $dob);

    $year_diff  = date("Y") - $year;
    $month_diff = date("m") - $month;
    $day_diff   = date("d") - $day;

    if ($day_diff < 0 || $month_diff < 0)
        $year_diff--;

    return $year_diff;
}
Фил Льюис
источник
2
Пожалуйста, подробно о том, как это будет полезно. Просто вставка функции не является правильным способом ответа.
Starx
3
$birthday_timestamp = strtotime('1988-12-10');  

// Calculates age correctly
// Just need birthday in timestamp
$age = date('md', $birthday_timestamp) > date('md') ? date('Y') - date('Y', $birthday_timestamp) - 1 : date('Y') - date('Y', $birthday_timestamp);
Дмитрий
источник
3

i18n:

function getAge($birthdate, $pattern = 'eu')
{
    $patterns = array(
        'eu'    => 'd/m/Y',
        'mysql' => 'Y-m-d',
        'us'    => 'm/d/Y',
    );

    $now      = new DateTime();
    $in       = DateTime::createFromFormat($patterns[$pattern], $birthdate);
    $interval = $now->diff($in);
    return $interval->y;
}

// Usage
echo getAge('05/29/1984', 'us');
// return 28
younes0
источник
3

Попробуйте любой из них, используя объект DateTime

$hours_in_day   = 24;
$minutes_in_hour= 60;
$seconds_in_mins= 60;

$birth_date     = new DateTime("1988-07-31T00:00:00");
$current_date   = new DateTime();

$diff           = $birth_date->diff($current_date);

echo $years     = $diff->y . " years " . $diff->m . " months " . $diff->d . " day(s)"; echo "<br/>";
echo $months    = ($diff->y * 12) + $diff->m . " months " . $diff->d . " day(s)"; echo "<br/>";
echo $weeks     = floor($diff->days/7) . " weeks " . $diff->d%7 . " day(s)"; echo "<br/>";
echo $days      = $diff->days . " days"; echo "<br/>";
echo $hours     = $diff->h + ($diff->days * $hours_in_day) . " hours"; echo "<br/>";
echo $mins      = $diff->h + ($diff->days * $hours_in_day * $minutes_in_hour) . " minutest"; echo "<br/>";
echo $seconds   = $diff->h + ($diff->days * $hours_in_day * $minutes_in_hour * $seconds_in_mins) . " seconds"; echo "<br/>";

Ссылка http://www.calculator.net/age-calculator.html

Шайлеш Сонаре
источник
3

Напишите PHP-скрипт для расчета текущего возраста человека.

Пример даты рождения: 11.4.1987

Пример решения:

PHP-код:

<?php
$bday = new DateTime('11.4.1987'); // Your date of birth
$today = new Datetime(date('m.d.y'));
$diff = $today->diff($bday);
printf(' Your age : %d years, %d month, %d days', $diff->y, $diff->m, $diff->d);
printf("\n");
?>

Пример вывода:

Ваш возраст: 30 лет, 3 месяца, 0 дней

Хосам Эльзаг
источник
2

это моя функция для расчета DOB с конкретным возвратом возраста по году, месяцу и дню

function ageDOB($y=2014,$m=12,$d=31){ /* $y = year, $m = month, $d = day */
date_default_timezone_set("Asia/Jakarta"); /* can change with others time zone */

$ageY = date("Y")-intval($y);
$ageM = date("n")-intval($m);
$ageD = date("j")-intval($d);

if ($ageD < 0){
    $ageD = $ageD += date("t");
    $ageM--;
    }
if ($ageM < 0){
    $ageM+=12;
    $ageY--;
    }
if ($ageY < 0){ $ageD = $ageM = $ageY = -1; }
return array( 'y'=>$ageY, 'm'=>$ageM, 'd'=>$ageD );
}

это как его использовать

$ age = ageDOB (1984, 5,8); / * с моим местным временем 2014-07-01 * /
echo sprintf ("age =% d лет% d месяцев% d дней", $ age ['y'], $ age ['m'], $ age ['d']); / * вывод -> возраст = 29 лет 1 месяц 24 дня * /
MdPutra
источник
2

Эта функция возвращает возраст в годах. Входное значение - это дата в формате (ГГГГ-ММ-ДД) дня рождения, например: 2000-01-01

Работает с точностью до дня

function getAge($dob) {
    //calculate years of age (input string: YYYY-MM-DD)
    list($year, $month, $day) = explode("-", $dob);

    $year_diff  = date("Y") - $year;
    $month_diff = date("m") - $month;
    $day_diff   = date("d") - $day;

    // if we are any month before the birthdate: year - 1 
    // OR if we are in the month of birth but on a day 
    // before the actual birth day: year - 1
    if ( ($month_diff < 0 ) || ($month_diff === 0 && $day_diff < 0))
        $year_diff--;   

    return $year_diff;
}

Ура, нира

нира
источник
1

Если вы не можете использовать некоторые из более новых функций, вот что я подхватил. Вероятно, больше, чем нужно, и я уверен, что есть лучшие способы, но их легко прочитать, поэтому они должны выполнить свою работу:

function get_age($date, $units='years')
{
    $modifier = date('n') - date('n', strtotime($date)) ? 1 : (date('j') - date('j', strtotime($date)) ? 1 : 0);
    $seconds = (time()-strtotime($date));
    $years = (date('Y')-date('Y', strtotime($date))-$modifier);
    switch($units)
    {
        case 'seconds':
            return $seconds;
        case 'minutes':
            return round($seconds/60);
        case 'hours':
            return round($seconds/60/60);
        case 'days':
            return round($seconds/60/60/24);
        case 'months':
            return ($years*12+date('n'));
        case 'decades':
            return ($years/10);
        case 'centuries':
            return ($years/100);
        case 'years':
        default:
            return $years;
    }
}

Пример использования:

echo 'I am '.get_age('September 19th, 1984', 'days').' days old';

Надеюсь это поможет.

maiorano84
источник
1

Из-за високосного года нецелесообразно просто вычитать одну дату из другой и ставить ее в число лет. Чтобы рассчитать возраст как у людей, вам понадобится что-то вроде этого:

$birthday_date = '1977-04-01';
$age = date('Y') - substr($birthday_date, 0, 4);
if (strtotime(date('Y-m-d')) - strtotime(date('Y') . substr($birthday_date, 4, 6)) < 0)
{
    $age--;
}
mileusna
источник
1

Нижеследующее прекрасно работает для меня и кажется намного проще, чем примеры, которые уже были приведены.

$dob_date = "01";
$dob_month = "01";
$dob_year = "1970";
$year = gmdate("Y");
$month = gmdate("m");
$day = gmdate("d");
$age = $year-$dob_year; // $age calculates the user's age determined by only the year
if($month < $dob_month) { // this checks if the current month is before the user's month of birth
  $age = $age-1;
} else if($month == $dob_month && $day >= $dob_date) { // this checks if the current month is the same as the user's month of birth and then checks if it is the user's birthday or if it is after it
  $age = $age;
} else if($month == $dob_month && $day < $dob_date) { //this checks if the current month is the user's month of birth and checks if it before the user's birthday
  $age = $age-1;
} else {
  $age = $age;
}

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

JustSomeGuy
источник
1

Следуя первой логике, вы должны использовать = в сравнении.

<?php 
    function age($birthdate) {
        $birthdate = strtotime($birthdate);
        $now = time();
        $age = 0;
        while ($now >= ($birthdate = strtotime("+1 YEAR", $birthdate))) {
            $age++;
        }
        return $age;
    }

    // Usage:

    echo age(implode("-",array_reverse(explode("/",'14/09/1986')))); // format yyyy-mm-dd is safe!
    echo age("-10 YEARS") // without = in the comparison, will returns 9.

?>
maikelsalazar
источник
Downvoted. В то время как это работает, неэффективно использовать цикл, чтобы сделать основную математику.
Wranorn
1

Это проблема, когда вы используете strtotime с ДД / ММ / ГГГГ. Вы не можете использовать этот формат. Вместо этого вы можете использовать ММ / ДД / ГГГГ (или многие другие, такие как ГГГГММДД или ГГГГ-ММ-ДД), и он должен работать правильно.

Бруно Фоджа
источник
1

Как насчет запуска этого запроса и расчета MySQL для вас:

SELECT 
username
,date_of_birth
,(PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m') )) DIV 12 AS years
,(PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m') )) MOD 12 AS months
FROM users

Результат:

r2d2, 1986-12-23 00:00:00, 27 , 6 

У пользователя есть 27 лет и 6 месяцев (это считается целый месяц)

Артур Кендзиор
источник
На самом деле это хорошее решение для людей с версиями PHP до 5.3, которые не имеют доступа к date_diff и тому подобному.
strangerstudios
1

Я сделал это так.

$geboortedatum = 1980-01-30 00:00:00;
echo leeftijd($geboortedatum) 

function leeftijd($geboortedatum) {
    $leeftijd = date('Y')-date('Y', strtotime($geboortedatum));
    if (date('m')<date('m', strtotime($geboortedatum)))
        $leeftijd = $leeftijd-1;
    elseif (date('m')==date('m', strtotime($geboortedatum)))
       if (date('d')<date('d', strtotime($geboortedatum)))
           $leeftijd = $leeftijd-1;
    return $leeftijd;
}
Smorvy
источник
1

Лучший ответ на этот вопрос - ОК, но он рассчитывает только год, когда родился человек, я настроил его для своих собственных целей, чтобы определить день и месяц. Но думал, что стоит поделиться.

Это работает, используя временную метку пользователей DOB, но вы можете изменить это

$birthDate = date('d-m-Y',$usersDOBtimestamp);
$currentDate = date('d-m-Y', time());
//explode the date to get month, day and year
$birthDate = explode("-", $birthDate);
$currentDate = explode("-", $currentDate);
$birthDate[0] = ltrim($birthDate[0],'0');
$currentDate[0] = ltrim($currentDate[0],'0');
//that gets a rough age
$age = $currentDate[2] - $birthDate[2];
//check if month has passed
if($birthDate[1] > $currentDate[1]){
      //user birthday has not passed
      $age = $age - 1;
} else if($birthDate[1] == $currentDate[1]){ 
      //check if birthday is in current month
      if($birthDate[0] > $currentDate[0]){
            $age - 1;
      }


}
   echo $age;
Пол Леджер
источник
1

Если вы хотите, чтобы вам было всего полных лет, есть очень простой способ сделать это. считать даты в формате «ГГГГММДД» числами и вычесть их. После этого отмените часть MMDD, разделив результат на 10000 и записав его. Простой и никогда не подводит, даже учитывает високосные годы и ваше текущее время сервера;)

Начиная с дня рождения или, в основном, указываются полные даты на месте рождения, и они имеют отношение к ТЕКУЩЕМУ МЕСТНОМУ ВРЕМЕНИ (где проверка возраста фактически выполняется).

$now = date['Ymd'];
$birthday = '19780917'; #september 17th, 1978
$age = floor(($now-$birtday)/10000);

так что если вы хотите проверить, есть ли у кого-то 18, 21 или ниже 100 в вашем часовом поясе (не говоря уже о часовом поясе происхождения) к дню рождения, это мой способ сделать это

simplemath
источник
0

Попробуй это :

<?php
  $birth_date = strtotime("1988-03-22");
  $now = time();
  $age = $now-$birth_date;
  $a = $age/60/60/24/365.25;
  echo floor($a);
?>
Майкл
источник