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 mr@sandman.net

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