php date('d') calculates same output for t

2019-07-31 16:53发布

问题:

I'm building a calendar through PHP and the way I'm doing this results on some days being written twice.

I replicated the behaviour in this little script:

<?php
//
// define a date to start from
//
$d = 26;
$m = 10;
$y = 2013;
date_default_timezone_set('CET');
$time = mktime(0, 0, 0, $m, $d, $y);

//
// calculate 10 years
//
for($i=0;$i<3650;$i++){ 
  $tomorrowTime = $time + (60 * 60 * 24);

  //
  // echo date if the next day has the same date('d') result
  //
  if(date('d',$time)==date('d',$tomorrowTime)){
    echo date('d-m-Y',$time)." was calculated twice... \n";
  }

  $time = $tomorrowTime;
}

?>

This is what I get:

27-10-2013 was calculated twice... 
26-10-2014 was calculated twice... 
25-10-2015 was calculated twice... 
30-10-2016 was calculated twice... 
29-10-2017 was calculated twice... 
28-10-2018 was calculated twice... 
27-10-2019 was calculated twice... 
25-10-2020 was calculated twice... 
31-10-2021 was calculated twice... 
30-10-2022 was calculated twice... 

When I define $time as 0 (unix epoch), I don't get the same behaviour. Is there something wrong with using mktime()? Or is November just being awkward?

Cheers, Jeroen

回答1:

This statement should guard better against leap seconds and such:

$tomorrowTime = strtotime('+1 days', $time);


回答2:

Makes sense, these are leap seconds. Not all days take 86400 seconds.

Don't use 12 AM for these calculations, use 12 PM. That'll help a lot.

That said, there are better approaches for date calculations. But your math with 12 PM will work fine for the UTC timezone (or CET).



回答3:

That's exactly why you don't add seconds to calculate times. DST and leap seconds make it so there are not always exactly 60 * 60 * 24 seconds in one day. You can use mktime for the correct calculations:

for ($i = 0; $i < 3650; $i++) { 
    $time = mktime(0, 0, 0, $m, $d + $i, $y);
    //                          ^^^^^^^

    ...
}


标签: php date mktime