P. Samuel P. Samuel - 5 months ago 7
PHP Question

How to show calendar month's previous days?

I'm trying to make a calendar that shows this month, and then fills in the remaining days on the end rows with the dates from the next and previous months.

I managed to make it show next months dates and the thing is the issue is that I need it to show previous months dates as well.

If someone manages to figure out the issues please add what the problem was as well how you managed to fix it, to help me in the future.

I will add a image of the calendar as well.

Image

The script:

<table cellspacing="0" cellpadding="0" border="0" width="100%" class="view-calendar">
<tr>
<td valign="top" width="14.2857%">Mondag</td>
<td valign="top" width="14.2857%">Tuesday</td>
<td valign="top" width="14.2857%">Wednesday</td>
<td valign="top" width="14.2857%">Thursday</td>
<td valign="top" width="14.2857%">Friday</td>
<td valign="top" width="14.2857%">Saturday</td>
<td valign="top" width="14.2857%">Sunday</td>
</tr>

<?php
// Get current month dates
$days_count = date('t');
$current_day = date('d');
$week_day_first = date('N', mktime(0, 0, 0, date('m'), 1, date('Y')));

// Get previous month dates

// Get next month dates
$next_start = strtotime(date("Y-m-00", strtotime("+1 month")));
$next_dates = array();

for ($w = 1 - $week_day_first + 1; $w <= $days_count; $w = $w + 7){
echo '<tr>';
$counter = 0;
for ($d = $w; $d <= $w + 6; $d++){
if($d < 10){
$current_date = date("Y").date("m").'0'.$d;
}else{
$current_date = date("Y").date("m").$d;
}
echo '<td valign="top" width="14.2857%"'.(($d > 0 ? ($d > $days_count ? ' class="disabled"' : '') : ' class="disabled"')).(($counter > 4 ? ' class="week-day"' : '')).'>';
if($d > 0){
if($d > $days_count){
for($in = 1; $in <= 1; $in++){
echo array_push($next_dates, date('j', strtotime("+ $in day", $next_start)));
}
}else if($current_day == $d){
echo '<div class="current-day"><span class="given-date">'.$d.'</span></div>';
}else{
echo '<span class="given-date">'.$d.'</span>';
}
}else{
//Here comes previous dates
}
echo '</td>';
$counter++;
}
echo '</tr>';
}
?>
</table>

Answer

When you calculated $week_day_first, you can save your time calculated from the first day of the month into a variable.

$time_first_day_of_month = mktime(0, 0, 0, date('m'), 1, date('Y'));

Then you can reuse that later to calculate the offset of days before the first of the month.

date('d', strtotime("$offset day",$time_first_day_of_month))

Putting it all together:

<table cellspacing="0" cellpadding="0" border="0" width="100%" class="view-calendar">
<tr>
<td valign="top" width="14.2857%">Mondag</td>
<td valign="top" width="14.2857%">Tuesday</td>
<td valign="top" width="14.2857%">Wednesday</td>
<td valign="top" width="14.2857%">Thursday</td>
<td valign="top" width="14.2857%">Friday</td>
<td valign="top" width="14.2857%">Saturday</td>
<td valign="top" width="14.2857%">Sunday</td>
</tr>

<?php
// Get current month dates
$days_count = date('t');

$current_day = date('d');

// save time of first day for later use
$time_first_day_of_month = mktime(0, 0, 0, date('m'), 1, date('Y'));
$week_day_first = date('N', $time_first_day_of_month);

// Get next month dates
$next_start = strtotime(date("Y-m-00", strtotime("+1 month")));

$next_dates = array();

for ($w = 1 - $week_day_first + 1; $w <= $days_count; $w = $w + 7){
  echo '<tr>';
  $counter = 0;
    for ($d = $w; $d <= $w + 6; $d++){
      if($d < 10){
        $current_date = date("Y").date("m").'0'.$d;
      }else{
        $current_date = date("Y").date("m").$d;
      }
      echo '<td valign="top" width="14.2857%"'.(($d > 0 ? ($d > $days_count ? ' class="disabled"' : '') : ' class="disabled"')).(($counter > 4 ? ' class="week-day"' : '')).'>';
      if($d > 0){
        // next month's dates
        if($d > $days_count){
          for($in = 1; $in <= 1; $in++){
            echo array_push($next_dates, date('j', strtotime("+ $in day", $next_start)));
          }
        }
        // today
        else if($current_day == $d){
          echo '<div class="current-day"><span class="given-date">'.$d.'</span></div>';
        }
        // this month's dates
        else{
          echo '<span class="given-date">'.$d.'</span>';
        }
      }
      // last month's dates
      else{
        //Here comes previous dates
        $offset = $d - 1;
        echo '<span class="given-date">'.date('d', strtotime("$offset day",$time_first_day_of_month)).'</span>';
      }
      echo '</td>';
      $counter++;
    }
  echo '</tr>';
}
?>
</table>

Results in this output:

<table cellspacing="0" cellpadding="0" border="0" width="100%" class="view-calendar">
<tr>
<td valign="top" width="14.2857%">Mondag</td>
<td valign="top" width="14.2857%">Tuesday</td>
<td valign="top" width="14.2857%">Wednesday</td>
<td valign="top" width="14.2857%">Thursday</td>
<td valign="top" width="14.2857%">Friday</td>
<td valign="top" width="14.2857%">Saturday</td>
<td valign="top" width="14.2857%">Sunday</td>
</tr>

<tr><td valign="top" width="14.2857%" class="disabled"><span class="given-date">30</span></td><td valign="top" width="14.2857%" class="disabled"><span class="given-date">31</span></td><td valign="top" width="14.2857%"><span class="given-date">1</span></td><td valign="top" width="14.2857%"><span class="given-date">2</span></td><td valign="top" width="14.2857%"><span class="given-date">3</span></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">4</span></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">5</span></td></tr><tr><td valign="top" width="14.2857%"><span class="given-date">6</span></td><td valign="top" width="14.2857%"><span class="given-date">7</span></td><td valign="top" width="14.2857%"><span class="given-date">8</span></td><td valign="top" width="14.2857%"><span class="given-date">9</span></td><td valign="top" width="14.2857%"><span class="given-date">10</span></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">11</span></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">12</span></td></tr><tr><td valign="top" width="14.2857%"><span class="given-date">13</span></td><td valign="top" width="14.2857%"><span class="given-date">14</span></td><td valign="top" width="14.2857%"><span class="given-date">15</span></td><td valign="top" width="14.2857%"><span class="given-date">16</span></td><td valign="top" width="14.2857%"><div class="current-day"><span class="given-date">17</span></div></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">18</span></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">19</span></td></tr><tr><td valign="top" width="14.2857%"><span class="given-date">20</span></td><td valign="top" width="14.2857%"><span class="given-date">21</span></td><td valign="top" width="14.2857%"><span class="given-date">22</span></td><td valign="top" width="14.2857%"><span class="given-date">23</span></td><td valign="top" width="14.2857%"><span class="given-date">24</span></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">25</span></td><td valign="top" width="14.2857%" class="week-day"><span class="given-date">26</span></td></tr><tr><td valign="top" width="14.2857%"><span class="given-date">27</span></td><td valign="top" width="14.2857%"><span class="given-date">28</span></td><td valign="top" width="14.2857%"><span class="given-date">29</span></td><td valign="top" width="14.2857%"><span class="given-date">30</span></td><td valign="top" width="14.2857%" class="disabled">1</td><td valign="top" width="14.2857%" class="disabled" class="week-day">2</td><td valign="top" width="14.2857%" class="disabled" class="week-day">3</td></tr></table>