3

I am wondering what am I doing wrong?

I create php loop to display next 3 years months.

My code:

<div class="input-group col-lg-2 col-md-12 col-sm-12 search">
     <label class="bd-form-label">Dates</label>
     <select name="date" id="search_date">
       <?php                        
        echo '<option value="all">Any Month</option>';
        for ($i = 0; $i <= 36; $i++) {
          $time = strtotime(sprintf('+%d months', $i));
          $label = date('F Y', $time);
          echo "<option value='$label'>$label</option>";
        }
       ?>
     /select>
 </div> 

It does displaying all months but not February(2018-2019-2020)

enter image description here

Any feedback? Is it something with my code? Cause I can not find any errors

Maria
  • 760
  • 2
  • 9
  • 22

3 Answers3

4

We are at the end of month (october 30th). If you add a fixed time parameter to strtotime (beginning of current month, october 1st), february will appear on the list. The reason lies in how strtotime handles the "month" parameter.

<div class="input-group col-lg-2 col-md-12 col-sm-12 search">
     <label class="bd-form-label">Dates</label>
     <select name="date" id="search_date">
       <?php                        
        echo '<option value="all">Any Month</option>';
        $start = strtotime('first day of this month');
        for ($i = 0; $i <= 36; $i++) {
          $time = strtotime(sprintf('+%d months', $i), $start);
          $label = date('F Y', $time);
          echo "<option value='$label'>$label</option>";
        }
       ?>
     </select>
 </div> 
mch
  • 1,259
  • 15
  • 23
3

Start your iteration with the first day of the current month to yield the right results:

<?php

    $date = new \DateTime('first day of this month');

    for ($i = 0; $i <= 36; $i++) {
        $date->modify("+1 months");
        echo $date->format('F Y');
    }

?>

Will output:

November 2017 December 2017 January 2018 February 2018 March 2018 April 2018 ...

Markus Müller
  • 2,611
  • 1
  • 17
  • 25
1

The "+1 month" issue with strtotime

Considering the following comment from the PHP Manual:

As noted in several blogs, strtotime() solves the "+1 month" ("next month") issue on days that do not exist in the subsequent month differently than other implementations like for example MySQL.

<?php
echo date( "Y-m-d", strtotime( "2009-01-31 +1 month" ) ); // PHP:  2009-03-03
echo date( "Y-m-d", strtotime( "2009-01-31 +2 month" ) ); // PHP:  2009-03-31
?>

<?php
SELECT DATE_ADD( '2009-01-31', INTERVAL 1 MONTH ); // MySQL:  2009-02-28
?>

Solution:

A better idea would be to use a different string than +X month. Perhaps, a mm/dd format date $i/01 (there always be the first day of the month) or use mktime.

$time = mktime(0,0,0,$i,1); //seconds, minutes, hours, month, day

Mktime - Month parameter - The number of the month relative to the end of the previous year. Values 1 to 12 reference the normal calendar months of the year in question. Values less than 1 (including negative values) reference the months in the previous year in reverse order, so 0 is December, -1 is November, etc. Values greater than 12 reference the appropriate month in the following year(s).

Ofir Baruch
  • 10,323
  • 2
  • 26
  • 39