PHP calcola l'età


160

Sto cercando un modo per calcolare l'età di una persona, dato il suo DOB ​​nel formato gg / mm / aaaa.

Stavo usando la seguente funzione che ha funzionato bene per diversi mesi fino a quando una sorta di glitch ha impedito che il ciclo while non finisse mai e fermasse l'intero sito. Dal momento che ci sono quasi 100.000 DOB che passano attraverso questa funzione più volte al giorno, è difficile stabilire quale sia la causa.

Qualcuno ha un modo più affidabile per calcolare l'età?

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

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

EDIT: questa funzione sembra funzionare OK qualche volta, ma restituisce "40" per un DOB del 14/09/1986

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

Risposte:


193

Funziona benissimo.

<?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
D'accordo, a volte per quel formato dobbiamo usare mktime(). sembra che php abbia calcolato male strtotime()quel formato.
GusDeCooL

30
PHP sta strtotimecapisce perfettamente formati di data, non c'è bisogno di preoccuparsi: 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

Questa funzione è davvero più costosa rispetto alle altre soluzioni. Viene dall'uso eccessivo della funzione date ().
Jarzon,

Bella data proporzionale. Grazie
Roque Mejos,

172
$tz  = new DateTimeZone('Europe/Brussels');
$age = DateTime::createFromFormat('d/m/Y', '12/02/1973', $tz)
     ->diff(new DateTime('now', $tz))
     ->y;

A partire da PHP 5.3.0 puoi usare il pratico DateTime::createFromFormatper assicurarti che la tua data non venga scambiata per m/d/Yformato e DateIntervalclasse (via DateTime::diff) per ottenere il numero di anni tra ora e la data target.


1
Sembra promettente, ma sfortunatamente la maggior parte dell'hosting di server nel mio paese utilizza ancora PHP 5.2.x :(
GusDeCooL

3
Ha davvero bisogno di un fuso orario?
André Chalella,

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

Ho provato a usare DateTime () prima, ma questo congela lo script. Nei miei registri vedo Avviso PHP: date (): non è sicuro fare affidamento sulle impostazioni del fuso orario del sistema, anche quando aggiungo date_default_timezone_set ('Europa / Bruxelles');
stef,

1
Sei sicuro di aver rimosso il # prima di quella riga? Dovresti impostarlo in PHP.ini
Wernight il

Di solito è sicuro ignorare quell'avvertimento (specialmente in quel caso).
Wernight,


60

Metodo semplice per calcolare Age from dob:

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

31556926 è il numero di secondi in un anno.


16
uso eccessivo di funzioni ...$_age = floor((time() - strtotime('1986-09-16')) / 31556926);
Mavelo

4
La migliore soluzione ... 1 fodera, semplice ed evita di usare: mktime
Timmy

1
@RobertM. È così brutto in questo caso? Non penso che queste funzioni siano così complesse o "pesanti"
Dewan159

1
@ Dewan159 guarda la cronologia delle modifiche ... è stata cambiata per adattarla alla mia soluzione;)
Mavelo l'

4
Che dire dei secondi bisestili?
ksimka,

17

// Calcolatore di età

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
Migliore soluzione moderna 2016.
AlexioVay

14

Trovo che funzioni ed è semplice.

Sottrai dal 1970 perché strtotime calcola il tempo dal 1970-01-01 ( http://php.net/manual/en/function.strtotime.php )

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

risultati:

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

Quasi vero ... strtotime () calcola il tempo dal 1969-12-31 18:00:00
phoenix

8

Se vuoi caculare l'Età dell'uso del dob, puoi anche usare questa funzione. Utilizza l'oggetto 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

Ho pensato di buttarlo qui perché questa sembra essere la forma più popolare di questa domanda.

Ho eseguito un confronto di 100 anni su 3 dei più popolari tipi di funzioni di età che ho trovato per PHP e ho pubblicato i miei risultati (così come le funzioni) sul mio blog .

Come puoi vedere qui , tutte e 3 le funzioni si preformano bene con solo una leggera differenza sulla seconda funzione. Il mio suggerimento basato sui miei risultati è di usare la terza funzione a meno che tu non voglia fare qualcosa di specifico per il compleanno di una persona, nel qual caso la prima funzione fornisce un modo semplice per farlo esattamente.

Abbiamo riscontrato un piccolo problema con il test e un altro problema con il secondo metodo! Aggiornamento in arrivo sul blog presto! Per ora, prenderei atto che il 2o metodo è ancora quello più popolare che trovo online, e tuttavia quello con cui sto trovando le più inesattezze!

I miei suggerimenti dopo la mia recensione di 100 anni:

Se vuoi qualcosa di più allungato in modo da poter includere occasioni come compleanni e simili:

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

Ma se vuoi semplicemente conoscere l'età e niente di più, allora:

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

getAge('1980-02-29');

Vedi BLOG


Una nota chiave sul strtotimemetodo:

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

È possibile utilizzare la Carbonlibreria , che è un'estensione API per DateTime.

Puoi:

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

o:

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

1
Questa è una soluzione più pulita, ma richiede una libreria esterna che potrebbe non essere la migliore per ogni progetto
stef

1
il carbonio offre la proprietà magica age, che sta facendo a diffInYears. Quindi puoi scrivere:(new \Carbon\Carbon($date))->age
k0pernikus il

4

Se non hai bisogno di grande precisione, solo il numero di anni, potresti prendere in considerazione l'uso del codice qui sotto ...

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

Devi solo inserire questo in una funzione e sostituire la data "1971-11-20" con una variabile.

Si noti che la precisione del codice sopra non è elevata a causa degli anni bisestili, ovvero ogni 4 anni circa i giorni sono 366 anziché 365. L'espressione 60 * 60 * 24 * 365 calcola il numero di secondi in un anno - è possibile sostituirlo con 31536000.

Un'altra cosa importante è che a causa dell'uso di UNIX Timestamp ha sia il problema Anno 1901 che Anno 2038, il che significa che l'espressione sopra non funzionerà correttamente per le date prima dell'anno 1901 e dopo l'anno 2038.

Se riesci a convivere con le limitazioni sopra menzionate, quel codice dovrebbe funzionare per te.


cosa succederà nel 2038 "ogni sistema" andrà in crash se utilizza time ()?
Miguel,

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

1
Non funziona. La tua funzione indicherebbe che qualcuno nato il 1 settembre 1990 ha la stessa età di qualcuno nato il 1 ottobre 1990 - calcolerebbe (2010 - 1990) = 20 per entrambi.
PaulJWilliams,

di quale precisione hai bisogno? mese? giorno?
Sergey Eremin,

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

Sembra ok in alcune date ma per altri non restituisce nulla, presumibilmente se l'IF non viene rispettato?
stef,

3

Ho trovato questo script affidabile. Prende il formato della data come AAAA-mm-gg, ma potrebbe essere modificato abbastanza facilmente per altri formati.

/*
* 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
Per favore alcuni dettagli su come questo sarà utile. Basta incollare una funzione non è un modo corretto di rispondere.
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

3

Prova uno di questi usando l'oggetto 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/>";

Riferimento http://www.calculator.net/age-calculator.html


3

Scrivi uno script PHP per calcolare l'età attuale di una persona.

Esempio di data di nascita: 11.4.1987

Soluzione di esempio:

Codice 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");
?>

Uscita campione:

La tua età: 30 anni, 3 mese, 0 giorni


2

questa è la mia funzione per calcolare DOB con il ritorno specifico dell'età per anno, mese e giorno

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

questo come usarlo

$ age = ageDOB (1984,5,8); / * con l'ora locale è il 01/07/2014 * /
echo sprintf ("età =% d anni% d mesi% d giorni", $ age ['y'], $ age ['m'], $ age ['d']); / * output -> età = 29 anni 1 mese 24 giorni * /

2

Questa funzione restituirà l'età in anni. Il valore di input è una stringa di giorno di nascita (AAAA-MM-GG) formattata per data, ad es .: 2000-01-01

Funziona con la precisione del giorno

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

Saluti, Nira


1

Se non riesci a utilizzare alcune delle nuove funzioni, ecco qualcosa che ho creato. Probabilmente più del necessario e sono sicuro che ci sono modi migliori, ma è facile da leggere, quindi dovrebbe fare il lavoro:

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

Esempio di utilizzo:

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

Spero che questo ti aiuti.


1

A causa dell'anno bisestile, non è saggio solo sottrarre una data da un'altra e indicarla al numero di anni. Per calcolare l'età come gli umani, avrai bisogno di qualcosa del genere:

$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

Quanto segue funziona alla grande per me e sembra essere molto più semplice degli esempi che sono già stati forniti.

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

Ho testato e utilizzato attivamente questo codice, potrebbe sembrare un po 'ingombrante ma è molto semplice da usare e modificare ed è abbastanza preciso.


1

Seguendo la prima logica, devi usare = nel confronto.

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

?>

Downvoted. Mentre funziona è inefficiente utilizzare un ciclo per eseguire la matematica di base.
Wranorn,

1

È un problema quando si utilizza strtotime con GG / MM / AAAA. Non puoi usare quel formato. Invece puoi usare MM / GG / AAAA (o molti altri come AAAAMMGG o AAAA-MM-GG) e dovrebbe funzionare correttamente.


1

Che ne dici di lanciare questa query e far calcolare a MySQL per te:

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

Risultato:

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

L'utente ha 27 anni e 6 mesi (conta un mese intero)


Questa è in realtà una buona soluzione per le persone nelle versioni pre-5.3 di PHP che non hanno accesso a date_diff e simili.
Strangerstudios,

1

L'ho fatto così.

$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

La risposta migliore per questo è OK, ma solo calualtes l'anno in cui una persona è nata, l'ho modificata per i miei scopi per capire il giorno e il mese. Ma ho pensato che valesse la pena condividerlo.

Questo funziona prendendo un timestamp del DOB degli utenti, ma sentiti libero di cambiarlo

$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

Se vuoi avere il pieno solo con l'età, c'è un modo supersemplice per farlo. considera le date formattate come 'AAAAMMGG' come numeri e sottrale. Dopodiché annulla la parte MMDD dividendo il risultato per 10000 e abbassandolo. Semplice e non fallisce mai, prende anche in considerazione gli anni bisestili e il tempo corrente del server;)

Dal momento che i birthays o per lo più forniti da date complete sul luogo di nascita e sono rilevanti per l'ora locale attuale (dove il controllo dell'età è effettivamente fatto).

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

quindi se vuoi controllare se qualcuno ha 18 o 21 o meno di 100 nel tuo fuso orario (non importa il fuso orario di origine) per compleanno, questo è il mio modo di farlo


0

Prova questo :

<?php
  $birth_date = strtotime("1988-03-22");
  $now = time();
  $age = $now-$birth_date;
  $a = $age/60/60/24/365.25;
  echo floor($a);
?>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.