PHP Month View Calendar

December 3rd, 2008 by Peter Anselmo Leave a reply »

I recently had to develop a month view Calendar for a website I’m building.  While such a thing is very common, it presents a number of twists:

  • You can’t start it on the first of the month – The first will likely fall mid-week
  • To find the acutual first day of the week, you need to know how many days are in the previous month and count backwards
  • You cannot assume 4 weeks per month -most have 5 or 6
  • you will need to use the correct number of days in the month, and then add on the correct number of days of the next month to finish the week

After playing with a few algorithms, I decided to represent the month with a 2-dimensional array, one index for each week, and another for each day.  Then, you can put the actual string date in each value, or perhaps an array with that day’s events.  Without further ado:

<?php
//CreateMonthView -
//Takes one parameter: a unix timestamp anywhere in the month
function CreateMonthView( $now ) {

    //get numberic day of month (01-31)
    $dayOfMonth = strftime('%d', $now);
    //subtract as approptriate to get to start of month
    $monthStart = $now - (86400 * ($dayOfMonth -1));

    //get numeric day of week (0-6)
    $dayOfWeek = strftime('%w', $monthStart);

    //subtract appropriate number of days to get to the start of the week
    //this will usually be the last part of the previous month
    $calMonthStart = $monthStart - (86400 * $dayOfWeek );

    //initialize variables for while loop
    $thisWeekStart = $calMonthStart;
    $week = 1;
    $monthArray = array();

    //last day of month - text condition for while loop
    $lastDayOfMonth = mktime(23, 59, 59,
                             date("m", $now),
                             date("t", $now),
                             date("Y", $now));

    //foreach week, create a new array to hold the days
    while( $thisWeekStart <= $lastDayOfMonth ) {
        $monthArray[$week] = array();

        //iterate through week - adding each day as a value
        for( $i=0; $i<7; $i++) {
            //get timestamp for each day
            $dayOfWeek = $thisWeekStart + 86400 * $i;
            //convert to a and ISO date - seconds are too precise
            $date = date('Y-m-d',$dayOfWeek);

            //each day will be the value in the array
            $monthArray[$week][] = $date;
        }

        //increment sentinal variable and week counter
        $thisWeekStart = $dayOfWeek + 86400;
        $week++;
    }

    return $monthArray;
}
?>

Now you may be saying to yourself “okay, that’s all fine and good, but it doesn’t do anything on it’s own”, and you’d be right, it’s just a function.  To make something happen, you simply need to call it, and display the result.  Here is another snippet that does just that:

<?php
$month = CreateMonthView( mktime() ); //create the current month

echo '<table>';
foreach( $month as $week ) {
    echo '<tr>';

    foreach ($week as $day ) {
        if( $day == date('Y-m-d') ){
            //apply selector to distinguish today's date
            echo '<td class="today">';
        } else {
            echo '<td>';
        }
        //reduce the complete ISO date down to the day and display it
        echo substr($day, 8, 2);
        echo '</td>';
    }
    echo "</tr>\n";
}
echo '</table>';
?>

Viola! You can certainly copy and paste this code as is, but it’s not very visually exciting. Here’s an example. It could definitely use some styling – but I’ll leave that up to you.

Leave a Reply