PHP date/time handling puzzler
Posted: Tue Sep 29, 2009 7:32 pm
I've run into a puzzling issue about mktime() and what you can or can't expect to do with it. I had a problem which I've now avoided by using strtotime(), and that works fine, but I just don't understand why my first intuitive approach doesn't work reliably.
My understanding of PHP's datetime data type is that it represents the number seconds since the Unix Epoch (1/1/1970) and that you should be able to add and subtract seconds to change dates and times. Like to add one day to a datetime variable, you can simply add (60 * 60 * 24). Works like a champ, right? Well, only to a certain extent. First off, when I create a new datetime variable, say $dt = mktime(0, 0, 0, 10, 1, 2009), I get a number which I can display as date('Y-m-d', $dt) and, sure enough, it yields: "2009-10-01". But if I display date('Y-m-d h:i:s', $dt), it shows: "2009-10-01 12:00:00"--NOON?? But I specifically entered a zero for the hour in mktime(). How come it displays 12? Let's say I add a week: $dt = $dt + (60 * 60 * 24 * 7). I can verify that both are on a Wednesday with date('l', $dt). Fine, so far. but then if I repeatedly add weeks, after about 40 or so times in the loop, it seems to hit a snag, and suddenly backs up a day, so that now they show as TUESDAY! What happened?? Here's a little script that does this for 100 repetitions and displays the variables in an html table. Everything seems to match up for the first 43 iterations, then it hiccups, then goes on for another 53 or so rows, then hiccups again. I find it extremely confusing!
I note, in the Manual, that an earlier optional 7th parameter, $is_dst (is it Daylight Saving Time?), has been deprecated beginning with PHP 5.1.0. I don't know if this is involved in any way.
Can anyone shine some light on this behavior?
Don
My understanding of PHP's datetime data type is that it represents the number seconds since the Unix Epoch (1/1/1970) and that you should be able to add and subtract seconds to change dates and times. Like to add one day to a datetime variable, you can simply add (60 * 60 * 24). Works like a champ, right? Well, only to a certain extent. First off, when I create a new datetime variable, say $dt = mktime(0, 0, 0, 10, 1, 2009), I get a number which I can display as date('Y-m-d', $dt) and, sure enough, it yields: "2009-10-01". But if I display date('Y-m-d h:i:s', $dt), it shows: "2009-10-01 12:00:00"--NOON?? But I specifically entered a zero for the hour in mktime(). How come it displays 12? Let's say I add a week: $dt = $dt + (60 * 60 * 24 * 7). I can verify that both are on a Wednesday with date('l', $dt). Fine, so far. but then if I repeatedly add weeks, after about 40 or so times in the loop, it seems to hit a snag, and suddenly backs up a day, so that now they show as TUESDAY! What happened?? Here's a little script that does this for 100 repetitions and displays the variables in an html table. Everything seems to match up for the first 43 iterations, then it hiccups, then goes on for another 53 or so rows, then hiccups again. I find it extremely confusing!
I note, in the Manual, that an earlier optional 7th parameter, $is_dst (is it Daylight Saving Time?), has been deprecated beginning with PHP 5.1.0. I don't know if this is involved in any way.
Can anyone shine some light on this behavior?
Don
Code: Select all
<html>
<head>
<title>Date Test</title>
</head>
<body>
<table border='1'>
<tr><td> </td><td>Date in</td><td>+ 7 days</td><td>+ 604800 secs</td>
<td>DtTm in</td><td>DtTm Out Should be</td><td>DtTm Out Is, with calc</td></tr>
<?php
$dt = '2009-01-01';
for($i=1; $i<100; $i++) {
$yr = substr($dt,0,4);
$mo = substr($dt,5,2);
$da = substr($dt,8,2);
$dttm = mktime(0,0,0,$mo,$da,$yr);
$dttm2 = $dttm + 60 * 60 * 24 * 7;
$dttm3 = date(strtotime('+7 days', $dttm));
$dt2 = date('Y-m-d h:i:s',$dttm2);
$dt3 = date('Y-m-d h:i:s',$dttm3);
$dd = date('l',$dttm2);
echo "<tr><td>$i</td><td>$dt</td><td>$dt3</td><td>$dt2 - $dd</td>";
echo "<td>$dttm</td><td>$dttm3</td><td>$dttm2</td></tr>";
$dt = $dt2;
}
?>
</table>
</body>
</html>