Skip to main content
<?     function counttime($start$stop false$display "combined"$short false) {         # version 1.4         # Author: Jonas Eklundh Communication AB         require_once ("adodb_time.php");         if (!$stop$stop adodb_date("Y-m-d");         $result = [];                  $sec["seconds"] = 1;         $sec["minutes"] = $sec["seconds"]*60;         $sec["hours"] = $sec["minutes"]*60;         $sec["days"] = $sec["hours"]*24;         $sec["weeks"] = $sec["days"]*7;         $sec["months"] = $sec["days"]*28# 28 so "feb 01-feb 28" is considered one month         $sec["years"] = $sec["days"]*365# 365 includes leap years         $sec array_reverse($sec);         # make sure that $from is always the earliest date         $from $stop $start $start $stop;         $to $stop $start $stop $start;                  # extract the parts of each date, for adodb_mktime         $fp preg_split("/[ :-]/"$from);         $tp preg_split("/[ :-]/"$to);                  # get time         $target adodb_mktime(($tp[3] ?? false), ($tp[4] ?? false), ($tp[5] ?? false), ($tp[1] ?? false), ($tp[2] ?? false), ($tp[0] ?? false));         $source adodb_mktime(($fp[3] ?? false), ($fp[4] ?? false), ($fp[5] ?? false), ($fp[1] ?? false), ($fp[2] ?? false), ($fp[0] ?? false));                  # the difference, in seconds, between the two dates         $diff $target-$source;                  if (in_array($display, array("combined""array"))) {             unset($sec["weeks"]);             if ($diff >= $sec["years"]) {                 #debug("YES: " . $diff);                 #debug(adodb_date("Y-m-d", $source));                 for ($y adodb_date("Y"$source);$y <= adodb_date("Y"$target);$y++) {                     $day adodb_date("m-d"$source) == "02-29" 28 $fp[2]; # considering feb 29, since we can't use it consistently                     $comptime adodb_mktime(($fp[3] ?? false), ($fp[4] ?? false), ($fp[5] ?? false), ($fp[1] ?? false), $day$y); #stepping a full year into the future. i.e. same date                     if ($comptime $source && $comptime <= $target) {                         # if comptime is within the range, a full year has elapsed                         if (empty($result["years"])) $result["years"] = 0;                         $result["years"]++; # so we add a year to the result                         $diff $target-$comptime# and remove the time we're at from the diff                     }                 }             }             if ($diff >= $sec["months"] && $diff 0) {                 # Ok, the time left is at least one month long                 $starttime $target-$diff# This is the second we're starting on                 for ($i $starttime;$i <= $target;$i+= $sec["days"]) {                     $comp_day adodb_date("d"$source); # This is the day of month we're comparing against                     if ($comp_day adodb_date("t"$i)) $comp_day adodb_date("t"$i); #making sure we don't compare 31 jan to 31 feb                     if (date("d"$i) == $comp_day && $i != $starttime) {                         # It's the same day of month, so one month has passed                         # So we subtract the aggregated time from the diff                         $hour $fp[3] ?? "00"# if hour is specified, we need to use that as well                         $diff $target-strtotime(adodb_date("Y-m-$comp_day $hour:i"$i)); # setting diff to the amount of seconds so far                         if (empty($result["months"])) $result["months"] = 0;                         $result["months"]++; # and add one moth to the result.                                              }                 }             }             # now diff every other type (i.e. days and hours)             foreach(explode(",""days,hours,minutes") as $type) {                 if ($diff >= $sec[$type]) {                     $result[$type] = floor($diff/$sec[$type]);                     $diff-= $result[$type]*$sec[$type];                 }             }             if ($result){                 if ($display == "array") return $result;                 foreach($result as $type => $nr) {                     $text " " oom($nrlp(preg_replace("/s$/"""$type) , "L") , lp($type"L"));                     $last "and";                     if ($short){                         $text preg_replace("/^s(.).*$/""$1"$text);                         $last "&";                     }                     $out[] = "$nr$text";                 }                 return itemlist($out", "$last);             } else {                 return false;             }         }         elseif ($display == "months"){             if ($diff >= $sec["months"]){                 # Ok, counting only months can be a bit tricky                 $start $source;                 while (1){                     $start += ($sec["days"]*35);                     $start adodb_mktime(000adodb_date("m"$start), 1adodb_date("Y"$start));                     if ($start $target) break;                     if ($iterations++ > 200) break;                     $result["months"]++;                 }                 return $result["months"];             } else {                 return 0;             }         }         elseif ($display == "years"){             if ($diff >= $sec["years"]){                 $start $source;                 $iterations 0;                 $result = [];                 while (1){                     $start += ($sec["days"]*366);                     $start adodb_mktime(000adodb_date("m"$start), 1adodb_date("Y"$start));                     if ($start $target) break;                     if ($iterations++ > 200) break;                     if (empty($result["years"])) $result["years"] = 0;                     $result["years"]++;                 }                 return $result["years"];             } else {                 return 0;             }         }         elseif ($display == "rounded"){                          if ($diff 60){                 return lp("now");             }             foreach (array_reverse($sec) as $w => $s){                 if ($diff $s){                     $nr round($diff/$lasts0PHP_ROUND_HALF_DOWN);                     return  $nr SPACE oom($nrlp(preg_replace("/s$/"""$lastw) , "L") , lp($lastw"L")) . SPACE lp("ago""L");                 }                 $lasts $s;                 $lastw $w;             }         }         elseif ($display == "roundedshort"){                          if ($diff 60){                 return lp("now");             }             foreach (array_reverse($sec) as $w => $s){                 $w substr($w01);                 if ($diff $s){                     $nr round($diff/$lasts0PHP_ROUND_HALF_DOWN);                     return  $nr $lastw;                 }                 $lasts $s;                 $lastw $w;             }         }         elseif($sec[$display]) {             if ($display == "seconds") return $target $source;             return (int)(($target-$source) /$sec[$display]);         }     } ?>
Note that the code is the exact code that I am using and may use functions that are exclusive to my system, and as such may not be suitable for copy/paste. Plus, these functions can change at any time and any blogs/tutorials that depend on these functioning in a specific way may have changed since it was written. If such a discrepancy is found, please email me at

If the function "lp()" is used, it's my "Language Print" function, that translates phrases from english to the site language. So, instead of "lp('and')" you would use just "and".