I came across a problem having developed a site with a PHP 5.3 environment, when moving the site to the live environment the server was running PHP 5.2. Whilst the server gets upgraded I looked into getting the code to work in some form in the meantime. The main issues are the functions lcfirst() and date_diff(). The former is a simple fix, a function which lower-cases the first letter of a string — I was surprised this was only introduced in 5.3!
if(function_exists('lcfirst') === false) { function lcfirst($str) { $str[0] = strtolower($str[0]); return $str; } }
The issue with date_diff is it’s reliance on the DateInterval class, which as the name suggests is a native object introduced in 5.3 to represent the interval between two dates. The function ought to be functionally equivalent between both PHP 5.2 and 5.3, otherwise it would be useless. I found something that I am fairly happy with, in that it accepts the same inputs and outputs as the native 5.3 version. The calculations aren’t correct though, unfortunately, and it’s an incomplete implementation. I corrected the “invert” data type values returned, and also added support for “days” as these are the main things I am using.
/** * Workaround for PHP < 5.3.0 */ if(!function_exists('date_diff')) { class DateInterval { public $y; public $m; public $d; public $h; public $i; public $s; public $invert; public $days; public function format($format) { $format = str_replace('%R%y', ($this->invert ? '-' : '+') . $this->y, $format); $format = str_replace('%R%m', ($this->invert ? '-' : '+') . $this->m, $format); $format = str_replace('%R%d', ($this->invert ? '-' : '+') . $this->d, $format); $format = str_replace('%R%h', ($this->invert ? '-' : '+') . $this->h, $format); $format = str_replace('%R%i', ($this->invert ? '-' : '+') . $this->i, $format); $format = str_replace('%R%s', ($this->invert ? '-' : '+') . $this->s, $format); $format = str_replace('%y', $this->y, $format); $format = str_replace('%m', $this->m, $format); $format = str_replace('%d', $this->d, $format); $format = str_replace('%h', $this->h, $format); $format = str_replace('%i', $this->i, $format); $format = str_replace('%s', $this->s, $format); return $format; } } function date_diff(DateTime $date1, DateTime $date2) { $diff = new DateInterval(); if($date1 > $date2) { $tmp = $date1; $date1 = $date2; $date2 = $tmp; $diff->invert = 1; } else { $diff->invert = 0; } $diff->y = ((int) $date2->format('Y')) - ((int) $date1->format('Y')); $diff->m = ((int) $date2->format('n')) - ((int) $date1->format('n')); if($diff->m < 0) { $diff->y -= 1; $diff->m = $diff->m + 12; } $diff->d = ((int) $date2->format('j')) - ((int) $date1->format('j')); if($diff->d < 0) { $diff->m -= 1; $diff->d = $diff->d + ((int) $date1->format('t')); } $diff->h = ((int) $date2->format('G')) - ((int) $date1->format('G')); if($diff->h < 0) { $diff->d -= 1; $diff->h = $diff->h + 24; } $diff->i = ((int) $date2->format('i')) - ((int) $date1->format('i')); if($diff->i < 0) { $diff->h -= 1; $diff->i = $diff->i + 60; } $diff->s = ((int) $date2->format('s')) - ((int) $date1->format('s')); if($diff->s < 0) { $diff->i -= 1; $diff->s = $diff->s + 60; } $start_ts = $date1->format('U'); $end_ts = $date2->format('U'); $days = $end_ts - $start_ts; $diff->days = round($days / 86400); if (($diff->h > 0 || $diff->i > 0 || $diff->s > 0)) $diff->days += ((bool) $diff->invert) ? 1 : -1; return $diff; } }
It works pretty well (bar the inaccuracies), and hopefully I won’t have a use for it again anyway.
[...] http://michaeloldroyd.co.uk/2011/11/04/a-basic-date_diff-for-php-5-2/ [...]
Hi all,
i knew its a old post, but since php i got these errors:
Warning: date_diff() expects parameter 1 to be DateTime, string given in /mnt
it was working until php 5.3 cames out. Any ideas how to get it back to work with php 5.3?
[code]if (! function_exists(date_diff)) {
function date_diff($start_date, $end_date, $returntype="d")
{
if ($returntype == "s")
$calc = 1;
if ($returntype == "m")
$calc = 60;
if ($returntype == "h")
$calc = (60*60);
if ($returntype == "d")
$calc = (60*60*24);
$_d1 = explode("-", $start_date);
$y1 = $_d1[0];
$m1 = $_d1[1];
$d1 = $_d1[2];
$_d2 = explode("-", $end_date);
$y2 = $_d2[0];
$m2 = $_d2[1];
$d2 = $_d2[2];
if (($y1 2037) || ($y2 2037))
{
return 0;
} else
{
$today_stamp = mktime(0,0,0,$m1,$d1,$y1);
$end_date_stamp = mktime(0,0,0,$m2,$d2,$y2);
$difference = round(($end_date_stamp-$today_stamp)/$calc);
return $difference;
}
}[/code]
the line which reports these date_diff problem:
$no_days=date_diff($pickup_date, $return_date, $returntype=”d”)+1;
i checked it thousand times and i havent any ideas.
So what could be wrong? any ideas?
Wish all a great 2013!
From what I can see, your function uses the same function name, but the parameters don’t match the native version. Native PHP 5.3 accepts two DateTime objects (from and to), returning a DateInterval object. This makes them functionally inequivalent, so you can’t use one as a substitute for the other.
DateInterval date_diff ( DateTime $datetime1 , DateTime $datetime2 [, bool $absolute = false ] )
The easiest thing you could do is to rename your function, and find-replace this throughout your source tree (if it’s only a single project). Alternatively, you could convert your code to use the native date_diff in PHP 5.3. If you require 5.2 support you can always include and/or improve the date_diff included in this post
.
Super I ran into the same problem and your code was of great help. Thanks!