【问题标题】:PHP calculate agePHP计算年龄
【发布时间】:2011-04-16 03:44:46
【问题描述】:

我正在寻找一种方法来计算一个人的年龄,给定他们的出生日期,格式为 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;

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

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

【问题讨论】:

    标签: php


    【解决方案1】:
    //replace / with - so strtotime works
    $dob = strtotime(str_replace("/","-",$birthdayDate));       
    $tdate = time();
    return date('Y', $tdate) - date('Y', $dob);
    

    【讨论】:

    • 不起作用。您的函数将表明出生于 1990 年 9 月 1 日的人与出生于 1990 年 10 月 1 日的人年龄相同 - 它会计算 (2010 - 1990) = 20。
    • 您需要什么样的年龄精度?月?天?
    【解决方案2】:
     $date = new DateTime($bithdayDate);
     $now = new DateTime();
     $interval = $now->diff($date);
     return $interval->y;
    

    【讨论】:

    • 我之前尝试过使用 DateTime() 但这会冻结脚本。在我的日志中,我看到 PHP 警告:date(): 依赖系统的时区设置是不安全的,即使我添加了 date_default_timezone_set('Europe/Brussels');
    • 您确定删除了该行之前的#?你应该在 PHP.ini 中设置它
    • 忽略该警告通常是安全的(尤其是在这种情况下)。
    【解决方案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;
      }
    

    【讨论】:

    • 在某些日期似乎还可以,但对于其他日期,它什么也不返回,大概是如果不满足 IF 的话?
    【解决方案4】:
    $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)来获取之间的年数现在和目标日期。

    【讨论】:

    • 看起来很有希望,但不幸的是,我国的大多数服务器托管仍然使用 PHP 5.2.x :(
    • 真的需要时区吗?
    • @AndréChalella 不,但时区显然使它准确
    【解决方案5】:

    这很好用。

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

    【讨论】:

    • 同意,有时我们需要使用mktime()。似乎 php 用这种格式错误地计算了strtotime()
    • 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
    • 这个功能确实比其他解决方案成本更高。这是由于过度使用 date() 函数造成的。
    • 不错的按比例分配的日期。谢谢
    • 太复杂了,不应该是公认的答案。
    【解决方案6】:

    如果您不需要很高的精度,只需要年数,您可以考虑使用下面的代码...

     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.

    如果您可以忍受上述限制,那么该代码应该适合您。

    【讨论】:

    • 如果使用 time(),2038 年会发生什么“每个系统”都会崩溃?
    【解决方案7】:
    $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);
    

    【讨论】:

      【解决方案8】:

      我发现这个脚本可靠。它将日期格式为 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;
      }
      

      【讨论】:

      • 请详细说明这会有什么帮助。仅仅粘贴一个函数并不是正确的回答方式。
      【解决方案9】:

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

      我对我能找到的 3 种最流行的 PHP 年龄函数类型进行了 100 年比较,并将我的结果(以及函数)发布到 my blog

      如您所见there,所有 3 个功能都表现良好,仅在第 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');
      

      See BLOG


      关于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.
      

      【讨论】:

        【解决方案10】:

        如果你想计算使用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;
        
        }
        

        【讨论】:

          【解决方案11】:

          如果您似乎无法使用某些较新的功能,这是我整理的。可能比你需要的要多,我相信有更好的方法,但它很容易阅读,所以它应该可以完成这项工作:

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

          希望这会有所帮助。

          【讨论】:

            【解决方案12】:

            由于闰年,将一个日期从另一个日期减去并将其设为年数是不明智的。要像人类一样计算年龄,你需要这样的东西:

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

            【讨论】:

              【解决方案13】:

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

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

              31556926 是一年中的秒数。

              【讨论】:

              • 过度使用函数...$_age = floor((time() - strtotime('1986-09-16')) / 31556926);
              • 最佳解决方案 ... 1 班轮,简单且避免使用:mktime
              • @RobertM。在这种情况下有那么糟糕吗?我不认为这些功能那么复杂或“繁重”
              • 闰秒怎么样?
              • 这不起作用。 echo floor((strtotime('2010-03-05') - strtotime('2000-03-05')) / 31556926); 返回 9,但应该返回 10。
              【解决方案14】:

              以下内容对我来说非常有用,并且似乎比已经给出的示例要简单得多。

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

              我已经测试并积极使用此代码,它可能看起来有点麻烦,但使用和编辑非常简单,并且非常准确。

              【讨论】:

                【解决方案15】:

                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
                

                【讨论】:

                  【解决方案16】:

                  按照第一个逻辑,您必须在比较中使用 =。

                  <?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.
                  
                  ?>
                  

                  【讨论】:

                  • 投反对票。虽然它有效,但使用循环进行基本数学运算效率很低。
                  【解决方案17】:

                  这个功能很好用。对Parkyprg的代码略有改进

                  function age($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--;}
                   if ($day_diff < 0 && $month_diff < 0){$year_diff--;}
                   return $year_diff;
                  }
                  

                  【讨论】:

                  • 该代码让您深入了解年龄计算的工作原理。我建议在生产站点中使用其他人的代码。我保留这个答案,以便人们了解年龄计算的工作原理。
                  【解决方案18】:

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

                  【讨论】:

                    【解决方案19】:

                    我为此使用日期/时间:

                    $age = date_diff(date_create($bdate), date_create('now'))->y;
                    

                    【讨论】:

                    【解决方案20】:

                    如何启动这个查询并让 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个月(算整月)

                    【讨论】:

                    • 这对于那些使用 5.3 之前版本的 PHP 且无法访问 date_diff 等的人来说实际上是一个很好的解决方案。
                    【解决方案21】:

                    查看所提供的解决方案,我一直在思考现代教育在 IT 领域的弊端。大多数开发人员都忘记了即使是现代 CPU 也会执行条件运算符,而算术运算,尤其是 2 的幂运算更快。 所以我的目的是在 PHP 线程中展示这个解决方案,没有任何优化:

                      list($year,$month,$day) = explode("-",$birthday);
                      $age=floor(((date("Y")-$year)*512+(date("m")-$month)*32+date("d")-$day)/512);
                    

                    在其他具有严格类型定义并且能够用移位替换 * 和 / 的语言中, 这个公式会“飞”。还可以更改除数,您可以按月、周等计算年龄。 注意,不同的操作数的顺序很重要

                    【讨论】:

                      【解决方案22】:

                      这是我计算 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("年龄 = %d 年 %d 个月 %d 天",$age['y'],$age['m'],$age['d']); /* 输出 -> 年龄 = 29 年 1 月 24 天 */

                      【讨论】:

                        【解决方案23】:

                        我是这样做的。

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

                        【讨论】:

                          【解决方案24】:

                          试试这个:

                          <?php
                            $birth_date = strtotime("1988-03-22");
                            $now = time();
                            $age = $now-$birth_date;
                            $a = $age/60/60/24/365.25;
                            echo floor($a);
                          ?>
                          

                          【讨论】:

                            【解决方案25】:

                            我使用以下方法计算年龄:

                            $oDateNow = new DateTime();
                            $oDateBirth = new DateTime($sDateBirth);
                            
                            // New interval
                            $oDateIntervall = $oDateNow->diff($oDateBirth);
                            
                            // Output
                            echo $oDateIntervall->y;
                            

                            【讨论】:

                              【解决方案26】:

                              对此的最佳答案是可以的,但只计算一个人出生的年份,我出于自己的目的对其进行了调整以计算出日期和月份。但觉得值得分享。

                              这是通过获取用户出生日期的时间戳来实现的,但可以随意更改

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

                              【讨论】:

                                【解决方案27】:

                                我发现这很有效而且很简单。

                                从 1970 年减去,因为 strtotime 从 1970 年 1 月 1 日开始计算时间 (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 开始计算时间
                                【解决方案28】:

                                如果您只想获得完整的年龄,有一种超级简单的方法可以做到这一点。将格式为“YYYYMMDD”的日期视为数字并减去它们。之后,通过将结果除以 10000 来消除 MMDD 部分并将其降低。简单且永不失败,甚至考虑闰年和您当前的服务器时间;)

                                自生日起或主要由出生地点的完整日期提供,并且与当前当地时间(实际完成年龄检查的时间)相关。

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

                                因此,如果您想在生日之前检查某人在您的时区(不管原始时区)是否为 18 岁或 21 岁或低于 100 岁,这是我的方法

                                【讨论】:

                                  【解决方案29】:

                                  此函数将返回以年为单位的年龄。输入值是日期格式 (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;
                                  }
                                  

                                  干杯,尼拉

                                  【讨论】:

                                    【解决方案30】:

                                    这是计算年龄的简单函数:

                                    <?php
                                        function age($birthDate){
                                          //date in mm/dd/yyyy format; or it can be in other formats as well
                                          //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]));
                                         return $age;
                                        }
                                    
                                        ?>
                                    
                                        <?php
                                        echo age('11/05/1991');
                                        ?>
                                    

                                    【讨论】:

                                      猜你喜欢
                                      • 2020-12-28
                                      • 2012-03-26
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2011-03-23
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2016-03-20
                                      相关资源
                                      最近更新 更多