Published on 13 May 2010. Tagged with programming, php, snippet.
/**
* Returns the table layout of a given month as an array of rows.
*
* <p>Padding will be added as necessary.</p>
*
* <p>Example: Return value for May 2010</p>
*
* <pre>
* array(
* array(null, null, null, null, null, 1, 2),
* array( 3, 4, 5, 6, 7, 8, 9),
* array( 10, 11, 12, 13, 14, 15, 16),
* array( 17, 18, 19, 20, 21, 22, 23),
* array( 24, 25, 26, 27, 28, 29, 30),
* array( 31, null, null, null, null, null, null)
* )
* </pre>
*
* @param int $year Year to generate the layout of.
* @param int $month Month to generate the layout of.
* @param int $firstWeekday Weekday of first column. Works like date('w').
* Defaults to monday.
* @throws IllegalArgumentException
* @author Marc Ermshaus <marc@ermshaus.org>
* @version 2010-05-13
* @example http://ermshaus.org/2010/05/php-a-helper-function-for-rendering-calendar-table-layouts
* @return array
*/
function getMonthLayout($year, $month, $firstWeekday = 6)
{
$year = (int) $year;
$month = (int) $month;
$firstWeekday = (int) $firstWeekday;
if ($month < 1 || $month > 12) {
throw new InvalidArgumentException(
'$month has to be between 1 and 12.');
}
if ($firstWeekday < 0 || $firstWeekday > 6) {
throw new InvalidArgumentException(
'$firstWeekday has to be between 0 and 6.');
}
$data = array();
$dt = new DateTime($year . '-' . $month . '-01');
$t = $dt->format('t');
$w = $dt->format('w');
$w = ($w + $firstWeekday) % 7;
// Add padding values to first row
if ($w == 0) {
$row = array();
} else {
$row = array_fill(0, $w, null);
}
for ($i = 1; $i <= $t; $i++) {
$row[] = $i;
if (($i + $w) % 7 == 0) {
$data[] = $row;
$row = array();
}
}
// Add padding values to last row
$k = (7 - (($t + $w) % 7)) % 7;
if ($k > 0) {
$row = array_merge($row, array_fill(0, $k, null));
$data[] = $row;
}
return $data;
}
The following example renders all months from the year 2010.
<?php
$year = 2010;
$shift = 6; // Set first column to monday
$days = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
// Ring shift weekday names according to $shift parameter
for ($i = 0; $i < $shift; $i++) {
$popped = array_pop($days);
array_unshift($days, $popped);
}
$date = new DateTime();
?>
<?php for ($month = 1; $month <= 12; $month++):
$data = getMonthLayout($year, $month, $shift);
$date->setDate($year, $month, 1);
echo '<p>' . $date->format('F Y') . '</p>';
?>
<table border="1">
<tr>
<th>
<?php echo implode('</th><th>', $days); ?>
</th>
</tr>
<?php foreach ($data as $row): ?>
<tr>
<?php foreach ($row as $day): ?>
<?php if ($day == null): ?>
<td> </td>
<?php else: ?>
<td><?php echo $day; ?></td>
<?php endif; ?>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
<?php endfor; ?>