Reputation: 49
Anyone can explain me what is wrong with strtotime function in this example? I'm trying to count differences between dates. PHP 5.6.0 (cli) (built: Aug 28 2014 08:03:51) When i execute this loop it displays number 88 twice.
date_default_timezone_set('Europe/London');
for($i=1;$i<=100;$i++){
$daysAfterTime = floor( abs( strtotime('2014-01-01') - strtotime('2014-01-01 +'.$i.' days') )/(60*60*24));
echo $daysAfterTime.'<br/>';
}
Upvotes: 2
Views: 297
Reputation: 219824
strtotime()
is not intended for date math. The manual even says so.
Using this function for mathematical operations is not advisable.
Days are not exactly 60*60*24
seconds long, etc.
As mentioned in the comments DateTime()
is much better suited for this as it accounts for things like daylight savings time, leap year, etc. Here's an advanced way of performing the same operation using DateTime()
, DateInterval()
, and DatePeriod()
that is also clearer to anyone trying to figure out what's going on.
$start = new DateTimeImmutable('2014-01-01', new DateTimeZone('Europe/London'));
$finish = $start->modify('+101 days'); // extra day as the last day is not inclusive
$interval = new DateInterval('P1D'); // interval of one day
$period = new DatePeriod($start, $interval, $finish);
foreach ($period as $date) {
$diff = $start->diff($date);
echo $diff->days . "<br>";
}
Upvotes: 5
Reputation: 15464
date_default_timezone_set('Europe/London');
echo (strtotime('2014-01-01 +89 days') - strtotime('2014-01-01 +88 days'))/(60*60), ' hours per day';
// 23 hours per day
I think that Europe/London timezone uses DST
Info about DST of London: http://www.timeanddate.com/time/zone/uk/london
var_dump(date('Y-m-d',strtotime('2014-01-01 +88 days')));
// string(10) "2014-03-30"
P.S. Using date with z works as expected.
date_default_timezone_set('Europe/London');
for($i=1;$i<=100;$i++){
$daysAfterTime = date('z', strtotime('2014-01-01 +'.$i.' days')) - date('z', strtotime('2014-01-01'));
echo $daysAfterTime.PHP_EOL;
}
Upvotes: 1
Reputation: 41885
I don't know whats the expected output but the other 88 result is because of that floor()
function. It rounded the lowest value thus the 88 repeated. Switch the growing value minus the constant value instead so that you don't need to use abs()
and use ceil()
.
date_default_timezone_set('Europe/London');
for($i=1;$i<=100;$i++){
$daysAfterTime = ceil((strtotime('2014-01-01 +'.$i.' days') - strtotime('2014-01-01'))/(60*60*24));
echo $daysAfterTime.'<br/>';
}
Upvotes: 1