0

In PHP, I would like to calculate the age of a person. For example, Person A was born on "1790-06-09" and died in "1854", but there is also a possibility to have a person B who was born in "1954" and died on "1990-02-05". As one of the dates is not complete, Y (ie yyyy in ISO8601) can be regarded as Y-01-01. Y is available as a string.

I tried to convert the date string to DateTime and calculate (see below), but was not sure how to create Y-01-01, and how to cope with Person B's case in the same code for Person A.

$d1 = new DateTime($birthdate);
$d2 = new DateTime($deathdate);
$diff = $d2->diff($d1);

Clever solution is highly appreciated. Thank you!

user7665853
  • 195
  • 1
  • 15
  • Thing you have a problem with date before 1970-01-01 where the timestamp starts. `print date('Y-m-d',0)` http://stackoverflow.com/questions/2871264/using-strtotime-for-dates-before-1970 or http://stackoverflow.com/questions/33581012/create-date-object-in-php-for-dates-before-1970-in-certain-format?noredirect=1&lq=1 – JustOnUnderMillions Mar 07 '17 at 15:33
  • So what is the problem, is it not giving the exact result?? – Code Lღver Mar 07 '17 at 15:35
  • IF you not really need the days or month and just need the years then do it without `DateTime` – JustOnUnderMillions Mar 07 '17 at 15:35
  • Just convert 1954 to 1954-01-01 for example OR substring out the year only and compare those – clearshot66 Mar 07 '17 at 15:36
  • Ignore my first comment, DateTime works with dates before 1970. – JustOnUnderMillions Mar 07 '17 at 15:38
  • Note: Do `print $diff = $d2->diff($d1)->format("%Y");` if you want the diff in years. – JustOnUnderMillions Mar 07 '17 at 15:40
  • 1
    You need to decide how accurate you want the age to be, Do you want it to be `Years` as an `Int` or `Years` as a `decimal` or `Years`, `Months`, `Days`. There are several ways to have someone's age shown. Decide that first then you can figure out how to do the rest. You may not need the `DateTime` format, maybe you only need the `Year` from each date. – Mike Mar 07 '17 at 15:40
  • Thanks a lot everybody. I was too naive and did not think that deep. Year only is acceptable, but can be with months too. It is very helpful to know there are many ways to achieve. – user7665853 Mar 09 '17 at 14:11

2 Answers2

2

Use DateTime::createFromFormat()

$birthdate = "1790-06-09";
$deathdate = "1854";

$d1 = new DateTime($birthdate);
$d2 = DateTime::createFromFormat('Y', $deathdate);

echo $d1->diff($d2)->y;

Edit: You can check date format with preg_match. This is example of validating Y-m-d format:

function dateYmdValid($date){
    return (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $date)) ? true : false;
}

$birthdate = "1790-06-09";
$deathdate = "1854";

$d1 = dateYmdValid($birthdate) ? new DateTime($birthdate)
                               : DateTime::createFromFormat('Y', $birthdate);
$d2 = dateYmdValid($deathdate) ? new DateTime($deathdate)
                               : DateTime::createFromFormat('Y', $deathdate);

echo $d1->diff($d2)->y;

Output: 63

Daniel Lagiň
  • 698
  • 7
  • 18
  • But it doesn't cover the case when he says that he can receives only the year in the birthdate or death-date. The logic bust be applied to both variables. – nikoskip Mar 07 '17 at 15:44
  • @nikoskip Interesting, thanks for comment. Will look at it after work. I assume you can check if the given date is year or full date with `preg_match`. – Daniel Lagiň Mar 07 '17 at 15:57
1

Maybe this can help you:

<?php

function calculateAge($born, $death) {
    $born = strpos($born, '-') === false ? $born . '-01-01' : $born;
    $death = strpos($death, '-') === false ? $death . '-01-01' : $death;

    $d1 = new DateTime($born);
    $d2 = new DateTime($death);
    return $d2->diff($d1)->y;
}

You just need to check if the - char is present to assume that the date is "OK". I'm assuming also that you are going to receive always a valid date or only a year.

nikoskip
  • 1,860
  • 1
  • 21
  • 38