Question

I have asked this question before and accepted the answer but now I found that the php version on our server is 5.2 and DateTime::diff() is not working on that.

I want to calculate person's age in months plus days using date of birth and a given date.

Date Format Input: Y-m-d (example: 1986-08-23)

Output:

5 months and 20 days old.
150 months and 4 days old.
285 months and 30 days old.

Thanks

Was it helpful?

Solution

Here's a solution that'll accurately determine the number of months and number of days, including leap years. It assumes that things like July 21 to August 21 is 1 month 0 days, not 1 month 1 day, and that March 21 to April 20 is 0 months 30 days, not 1 month 0 days. The latter in both cases is what occurs when you just do a straight divide by 30 to calculate months.

I'm sure there's a better way to optimize the function, but it gets the job done:

function diff_date($start_date, $end_date) {
  list($start_year, $start_month, $start_day) = explode('-', $start_date);
  list($end_year, $end_month, $end_day) = explode('-', $end_date);

  $month_diff = $end_month - $start_month;
  $day_diff   = $end_day - $start_day;

  $months = $month_diff + ($end_year - $start_year) * 12;
  $days = 0;

  if ($day_diff > 0) {
    $days = $day_diff;
  }
  else if ($day_diff < 0) {
    $days = $end_day;
    $months--;

    if ($month_diff > 0) {
      $days += 30 - $start_day;

      if (in_array($start_month, array(1, 3, 5, 7, 8, 10, 12))) {
        $days++;
      }
      else if ($start_month == 2) {
        if (($start_year % 4 == 0 && $start_year % 100 != 0) || $start_year % 400 == 0) {
          $days--;
        }
        else {
          $days -= 2;
        }
      }

      if (in_array($end_month - 1, array(1, 3, 5, 7, 8, 10, 12))) {
        $days++;
      }
      else if ($end_month - 1 == 2) {
        if (($end_year % 4 == 0 && $end_year % 100 != 0) || $end_year % 400 == 0) {
          $days--;
        }
        else {
          $days -= 2;
        }
      }
    }
  }

  return array($months, $days);
}

list($months, $days) = diff_date('1984-05-26', '2010-04-29');

print $months . ' months and ' . $days . ' days old.';

Output:

314 months and 3 days old.


Edit: I tried to get rid of redundancy in the code, and forgot to rename a variable. This function will now work correctly for diff_date('2010-06-29', '2011-07-01').


Edit: Now correctly works for end months occurring after months with 31 or 28/29 days.

OTHER TIPS

Use your favorite date parsing function (strtotime, strptime, mktime) to get an UNIX timestamp out of the date, then the interval ($now - $then)... and then work out how many seconds there are in a month and use that to calculate how many months the person has lived (division and remainder are your friends).

This'll give you a mathematically precise value that should be close enough to real life too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top