Requesting help with date/time/age calculation function

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
rbsterli
Forum Newbie
Posts: 2
Joined: Thu Mar 23, 2006 8:05 pm

Requesting help with date/time/age calculation function

Post by rbsterli »

feyd | Please use

Code: Select all

and

Code: Select all

tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


Hi Folks!

PHP Newbie here and I got this little code snippet somewhere on the Internet recently.  It seems to work well for the most part but the "day" calculation seems to be off.  I've only been analyzing it for about 36 hours but I'm thinking it may be a timezone issue or something.  I'm using it on a page I created for a newborn so I wish to calculate his exact age in "days, minutes and seconds"

Minutes and seconds obviously aren't "required", but is a real neat novelty!  Anywho.. I am running this on my own Windows server which the Time and TZ are set correctly.  When I run phpinfo, it also shows correct time, but this snippet seems to jump to an additional day after 7:00PM EST.  Maybe it's off all the time, I can only confirm that tomorrow.  But.. Here's the code, I found it in a blog from 2002 and there is no way to contact the author.  Please help if anyone can.  Thanks in advance.

(I am trying to calculate age from a time of birth of 3/21/2006 10:21AM EST - [url=http://www.richsterling.com/forum/drew.php]EXAMPLE[/url])

Code: Select all

<?php
function date_delta($ts_start_date, $ts_end_date) {
  $secs_in_day = 86400;

  $i_years = gmdate('Y', $ts_end_date) - gmdate('Y', $ts_start_date);
  $i_months = gmdate('m', $ts_end_date) - gmdate('m', $ts_start_date);
  $i_days = gmdate('d', $ts_end_date) - gmdate('d', $ts_start_date);
  if ($i_days < 0)
    $i_months--;
  if ($i_months < 0) {
    $i_years--;
    $i_months += 12;
  }
  if ($i_days < 0) {
    $i_days = gmdate('d', gmmktime(0, 0, 0,
      gmdate('m', $ts_start_date)+1,
      0,
      gmdate('Y', $ts_start_date))) -
      gmdate('d', $ts_start_date);
    $i_days += gmdate('d', $ts_end_date);
  }

  # calculate HMS delta
  $f_delta = $ts_end_date - $ts_start_date;
  $f_secs = $f_delta % $secs_in_day;
  $f_secs -= ($i_secs = $f_secs % 60);
  $i_mins = intval($f_secs/60)%60;
  $f_secs -= $i_mins * 60;
  $i_hours = intval($f_secs/3600);

  return array($i_years, $i_months, $i_days,
               $i_hours, $i_mins, $i_secs);
}

function calculate_age($s_start_date,
    $s_end_date = '',
    $b_show_days = 0) {
  $b_show_time = strlen($s_start_date > ;
  $ts_start_date =
    mktime(substr($s_start_date, 8, 2),
      substr($s_start_date, 10, 2),
      substr($s_start_date, 12, 2),
      substr($s_start_date, 4, 2),
      substr($s_start_date, 6, 2),
      substr($s_start_date, 0, 4));
  if ($s_end_date) {
    $ts_end_date =
      mktime(substr($s_end_date, 8, 2),
        substr($s_end_date, 10, 2),
        substr($s_end_date, 12, 2),
        substr($s_end_date, 4, 2),
        substr($s_end_date, 6, 2),
        substr($s_end_date, 0, 4));
  } else {
    $ts_end_date = time();
  }

  list ($i_age_years, $i_age_months, $i_age_days,
        $i_age_hours, $i_age_mins, $i_age_secs) =
       date_delta($ts_start_date, $ts_end_date);

  # output
  $s_age = '';
  if ($i_age_years)
    $s_age .= "$i_age_years year".
      (abs($i_age_years)>1?'s':'');
  if ($i_age_months)
    $s_age .= ($s_age?', ':'').
      "$i_age_months month".
      (abs($i_age_months)>1?'s':'');
  if ($b_show_days && $i_age_days)
    $s_age .= ($s_age?', ':'').
      "$i_age_days day".
      (abs($i_age_days)>1?'s':'');

  if ($b_show_time && $i_age_hours)
    $s_age .= ($s_age?', ':'').
      "$i_age_hours hour".
      (abs($i_age_hours)>1?'s':'');
  if ($b_show_time && $i_age_mins)
    $s_age .= ($s_age?', ':'').
      "$i_age_mins minute".
      (abs($i_age_mins)>1?'s':'');
  if ($b_show_time && $i_age_secs)
    $s_age .= ($s_age?', ':'').
      "$i_age_secs second".
      (abs($i_age_secs)>1?'s':'');
  return $s_age;
}


?> 
<?= calculate_age('20060316102100','','1') ?>
Thanks again,
rbsterli
RichSterling.com - PC Support, Woodworking Links and BBQ Forums
Image


feyd | Please use

Code: Select all

and

Code: Select all

tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

This code is using gmdate which I would assume is using greenwhich meantime regardless of your timezone setting. You will need to subtract your timezone offset from it in order to get the correct results.
User avatar
rbsterli
Forum Newbie
Posts: 2
Joined: Thu Mar 23, 2006 8:05 pm

Post by rbsterli »

feyd | Please use

Code: Select all

and

Code: Select all

tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


Thanks.. I tried that.  It does adjust the hours, but it makes the hours 5 hours off.  It doesn't affect the day count.  The hours, minutes and seconds are always accurate - the number of days just reflect "an extra day" after 7PM.

-Weird.  I had a sigh of a days worth of research - relief, for a second.  Made the change and it didn't do it, although sounding very logical      Thanks though..

My guess is that I need to make up the 5 hour difference somewhere in this section where the days are calculated??   If this is correct, can anyone help tell me where???

Code: Select all

$i_days = gmdate('d', $ts_end_date) - gmdate('d', $ts_start_date); 
  if ($i_days < 0) 
    $i_months--; 
  if ($i_months < 0) { 
    $i_years--; 
    $i_months += 12; 
  } 
  if ($i_days < 0) { 
    $i_days = gmdate('d', gmmktime(0, 0, 0, 
      gmdate('m', $ts_start_date)+1, 
      0, 
      gmdate('Y', $ts_start_date))) - 
      gmdate('d', $ts_start_date); 
    $i_days += gmdate('d', $ts_end_date); 
  }

feyd | Please use

Code: Select all

and

Code: Select all

tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
Last edited by rbsterli on Thu Mar 23, 2006 8:40 pm, edited 1 time in total.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Code: Select all

function GetAge($DOB) {
  list($Year, $Month, $Day) = explode("-",$DOB);
  $YearDifference  = date("Y") - $Year;
  $MonthDifference = date("m") - $Month;
  $DayDifference   = date("d") - $day;
  if ($DayDifference < 0 || $MonthDifference < 0) {
    $YearDifference--;
  }
  return $YearDifference;
}
Here is a function I wrote which returns the age of someone in years based on a dob in the format 1980-01-28

It could be modified to return the age in Years, Months, days, Hours, Minutes and Seconds.
Post Reply