PHP计算年龄


160

考虑到他们的DOB格式为dd / mm / yyyy,我正在寻找一种计算年龄的方法。

我一直在使用以下功能,该功能在几个月内都工作良好,直到出现某种故障导致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;

编辑:此函数的某些时间似乎可以正常工作,但对于14年9月14日的DOB返回“ 40”

return floor((time() - strtotime($birthdayDate))/31556926);

Answers:


192

这很好。

<?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 2011年

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 2012年

此功能确实比其他解决方案昂贵。这是由于对date()函数的过度使用所致。
Jarzon

好的比例分配的日期。谢谢
Roque Mejos '16

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)可以获取从现在到目标日期之间的年数。


1
看起来很有希望,但不幸的是,我国的大多数服务器托管仍然使用PHP 5.2.x :(
GusDeCooL 2011年

3
真的需要时区吗?
安德烈(AndréChalella)2015年

127
 $date = new DateTime($bithdayDate);
 $now = new DateTime();
 $interval = $now->diff($date);
 return $interval->y;

我之前尝试过使用DateTime(),但这会冻结脚本。在我的日志中,我看到了PHP警告:date():即使添加date_default_timezone_set('Europe / Brussels');也不依靠系统的时区设置是不安全的。
2010年

1
您确定删除了该行之前的#吗?您应该在PHP.ini中进行设置
Wernight 2010年

通常可以忽略该警告(特别是在这种情况下)。
2010年


60

从dob计算年龄的简单方法:

$_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。在这种情况下真的很糟糕吗?我认为这些功能不是那么复杂或“繁重”
Dewan159

1
@ Dewan159查看编辑历史记录...已更改为匹配我的解决方案;)
Mavelo 2014年

4
leap秒呢?
ksimka '16

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

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;

}

8

我想把它放在这里,因为这似乎是这个问题的最流行形式。

我对可以在PHP上找到的3种最流行的年龄函数进行了100年的比较,并将我的结果(以及函数)发布到了我的博客上

正如你所看到那里,所有3个funcs中与二号功能只是一个细微的差别瓶坯很好。根据我的结果,我的建议是使用第3个函数,除非您想在一个人的生日上做一些特定的事情,在这种情况下,第1个函数提供了一种简单的方法来精确地做到这一点。

发现测试有小问题,而第二种方法又有问题!更新即将发布到博客!现在,我要指出的是,第二种方法仍然是我在网上找到的最受欢迎的方法,但仍然是我发现的最不正确的方法!

经过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.

8

您可以使用该Carbon,它是DateTime的API扩展。

您可以:

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

要么:

$age = (new \Carbon\Carbon($date))->age;

1
这是一个更清洁的解决方案,但它需要这可能不是最好的每一个项目的外部LIB
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”。

请注意,由于the年,上述代码的精度并不高,即大约每4年的天数是366而不是365。表达式60 * 60 * 24 * 365计算一年中的秒数-您可以将其替换为31536000。

另一个重要的事情是,由于使用了UNIX时间戳,它同时具有1901年和2038年的问题,这意味着上面的表达式在1901年之前和2038年之后的日期将无法正常工作。

如果您可以克服上述限制,那么该代码将为您工作。


如果使用time(),那么2038年“每个系统”都会崩溃吗?
米格尔(Miguel)

3
//replace / with - so strtotime works
$dob = strtotime(str_replace("/","-",$birthdayDate));       
$tdate = time();
return date('Y', $tdate) - date('Y', $dob);

1
不起作用。您的函数将表明在1990年9月1日出生的人与在1990年10月1日出生的人相同的年龄-它将计算出两个人的(2010-1990)= 20。
PaulJWilliams 2010年

您需要几岁的年龄?月?天?
谢尔盖·埃雷敏

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

在某些日期似乎还可以,但对于另一些日期,它似乎什么也没满足就什么都不返回?
2010年

3

我发现此脚本可靠。日期格式为YYYY-mm-dd,但可以很容易地将其修改为其他格式。

/*
* 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 2012年

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

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个月


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 years%d months%d days”,$ age ['y'],$ age ['m'],$ age ['d']); / *输出->年龄= 29年1个月24天* /

2

此函数将返回以年为单位的年龄。输入值是日期格式(YYYY-MM-DD)的生日字符串,例如: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';

希望这可以帮助。


1

由于leap年,仅从另一个日期减去一个日期并将其限制为年数是不明智的。要像人类一样计算年龄,您将需要以下内容:

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

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

我已经测试并积极使用了此代码,它看起来有些笨拙,但使用和编辑非常简单,而且非常准确。


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.

?>

不赞成投票。在运行时,使用循环执行基本数学效率不高。
Wranorn

1

将strtotime与DD / MM / YYYY一起使用时会出现问题。您不能使用该格式。代替它,您可以使用MM / DD / YYYY(或其他许多方式,例如YYYYMMDD或YYYY-MM-DD),它应该可以正常工作。


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个月的时间(计算一个月)


对于那些不能访问date_diff之类的PHP 5.3之前版本的人来说,这实际上是一个不错的解决方案。
陌生

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

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

如果您只想获得整年的年龄,则有一种非常简单的方法。将格式为“ YYYYMMDD”的日期视为数字并将其减去。之后,通过将结果除以10000并将其下限来取消MMDD部分。简单且永不失败,甚至无需考虑leap年和您当前的服务器时间;)

由于出生日期或大多数情况下是由出生日期的完整日期提供的,因此它们与当前的本地时间(实际进行年龄检查)相关。

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

因此,如果您想在生日之前检查某人在您的时区中是18岁,21岁还是100岁以下(不要考虑原始时区),这是我的方法


0

试试这个 :

<?php
  $birth_date = strtotime("1988-03-22");
  $now = time();
  $age = $now-$birth_date;
  $a = $age/60/60/24/365.25;
  echo floor($a);
?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.