Is this a PHP date() bug, or is there something wrong with my code?

夙愿已清 提交于 2019-12-28 04:32:29

问题


I've two images of an arrow, one which increments the month backward, one which increments it forward via href.

if (ISSET($_GET["month"])){
    $month_index = $_GET["month"];
}
else{
    $month_index = 0;
}
$month = strtotime("+".$month_index." month");
?>
...

<a href=<?php $month_index = $month_index - 1; echo "?month=".$month_index; ?>><img src="arrow_left.gif" ></a>
<div class="title">Logbook Calendar for <?php echo date("F Y",$month); ?> </div>
<a href=<?php $month_index = $month_index + 2; echo "?month=".$month_index; ?>><img src="arrow_right.gif"></a>

The issue is that when Feburary 2015 comes up, date() returns "March 2015"—so $month_index = 6 and $month_index = 7 are both March.

I ran this code on http://writecodeonline.com/php/:

date_default_timezone_set("America/New_York");
$month_index = 6;
$month_index = $month_index - 1;
$month_index = $month_index + 2; 
echo $month_index;
$month = strtotime("+".$month_index." month");
echo " " . $month;
echo " " . date("F Y",$month);

Switching $month_index=6 to $month_index=7 still results in March being echoed. Is there just some bug here where Feburary, 2015 is... gone?

Update: Thanks, everyone. I would've never found that on my own. I solved the problem this way:

$month = strtotime(date("M-01-Y") . "+".$month_index." month");

回答1:


It's how dates work and when you encounter February and the 29th day of the month or later. When you add a month to a date after the last day of February of that year (i.e. 28th of February this year) you will skip over February. Whenever iterating through months you should always work with the start of the month to avoid February being skipped. So if you start with January 30th and add "one month" since there is no Feb 30th you will skip ahead to March.

Here's how you can iterate through months without knowing how many days are in February (or caring). I picked an arbitrary end date of one year from now.

$start    = new DateTimeImmutable('@'.mktime(0, 0, 0, $month_index, 1, 2014));
$end      = $start->modify('+1 year')
$interval = new DateInterval('P1M');
$period   = new DatePeriod($start, $interval, $end);

foreach ($period as $dt) {
    echo $dt->format('F Y');
}



回答2:


There is no February 29th in 2015.

By just adding or subtracting whole months at a time, you create new dates on the same day in the requested month. In this case, you caused PHP to try and make a February 29, 2015 date. It automatically jumped forward to March 1, 2015.

If you only care about Months, create dates on the first of each month:

date("F y", mktime(0,0,0, $month_index, 1, 2015));

Good thing you are writing this code and caught the bug today, or you would have had a bug that only appeared on the 29th (or 31st) of every month (except leap years)!

Dates are hard.



来源:https://stackoverflow.com/questions/25022411/is-this-a-php-date-bug-or-is-there-something-wrong-with-my-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!