Pergunta

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

Foi útil?

Solução

This statement should guard better against leap seconds and such:

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

Outras dicas

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

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);
    //                          ^^^^^^^

    ...
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top