Think about the future, etc. I just wrote a calendar for work and tied in event databases, etc. But... I found that any given month may cross over anywhere from 4 weeks (sun-sat) to 6 weeks (See November 2003 and February 2009 for examples). Here's the code I wrote to deal with that, minus all my database stuff.
<?php
import_request_variables("gP", "rvar_");
// is this a clean visit or did they pick a month?
// if not chosen, pick this month
if(isset($rvar_aMonth)){
$month=$rvar_aMonth;
}else{
$month=date("n",time());
}
if(isset($rvar_aYear)){
$year=$rvar_aYear;
}else{
$year=date("Y",time());
}
// todays date components
$thisDay=date("j",time());
$thisMonth=date("n",time());
$thisYear=date("Y",time());
// full date in same format as in db
$today=$thisMonth."-".$thisDay."-".$thisYear;
// what is the name of the month that we are
// showing?
$monthName=date("F",mktime(0,0,0,$month,1,1999));
// how many days are in the month we are showing?
// leap years work fine
$numDaysInMonth = date("t", mktime(0, 0, 0, $month, 1, $year));
// what's the first day of the
//month we are showing (mon, tues, etc.)
$FirstDayOfMonth=date("w", mktime(0, 0, 0, $month, 1, $year));
// what day of the month (1-[28|29|30|31])
// we will increment as we display the grid
// and use it to build $fulldate (above)
$daynum=1;
// full date in same format as in db
$fulldate=$month."-".$daynum."-".$year;
// define some often used html tags to save typing
// and make it slightly easier to read.
// yes, this is what stylesheets are for (i guess)
// but I don't use 'em...
$hr="";
// header row <td>
$td="<td align=center width=80>";
// calendar body <td>
$td2="<td valign=top width=80 height=75>";
// calendar body <td> with a bgcolor
// if $today is being displayed
$td3="<td valign=top width=80 height=75 bgcolor=#eeeeee>";
// duh? yes, this saves a few characters...
$etd="</td>";
// shim image
//$shim="<img src=shim.gif width=1 height=1>\n";
$shim="";
// for a link to view the day
$dayview="<a href=\"#\" onClick=viewDay('";
print("\n<title>Steve's PHP Calendar ".$monthName." ".$year."</title>\n</head>\n");
?>
<body><!-- wrapper part 1 --><table width="100%" height="0" border="0" cellpadding="3" cellspacing="0">
<tr align="center" valign="top">
<td width="13%" align="left"><br>
<hr width=10>
</td>
<td width="87%" align="left">
<!-- month view container --><table width="100%" height="0" border="0" valign=top cellpadding="3" cellspacing="0">
<tr align="left" valign="top">
<td> <!-- grid table--><table border="1" cellspacing="0" cellpadding="2" width="700">
<tbody>
<tr align="center" bordercolor="#003366" bgcolor="#003366">
<td colspan="7" valign="middle">
<!-- search/nav table --> <table width=100% border=0 cellspacing=0 cellpadding=0><tr><td width=150>
<!-- search table --> <table width=100% border=0 cellspacing=0 cellpadding=0><tr><td>
</td></tr></table>
<!-- end text search -->
</td><td align=center width=225><form action="./month.php" name=frm method=POST><table width=150 border=0 cellspacing=1 cellpadding=1>
<tr><td><font size=1 color=#ffffff face="Arial, Helvetica, sans-serif">Jump To:<br></font>
<select name=aMonth>
<option value=1>January</option>
<option value=2>February</option>
<option value=3>March</option>
<option value=4>April</option>
<option value=5>May</option>
<option value=6>June</option>
<option value=7>July</option>
<option value=8>August</option>
<option value=9>September</option>
<option value=10>October</option>
<option value=11>November</option>
<option value=12>December</option>
</select></td><td><font size=1 color=#ffffff face="Arial, Helvetica, sans-serif"> <br></font><select name=aYear>
<option value=2003>2003</option>
<option value=2004>2004</option>
<option value=2005>2005</option>
<option value=2006>2006</option>
<option value=2007>2007</option>
<option value=2008>2008</option>
<option value=2009>2009</option>
<option value=2010>2010</option>
</select></td><td><font size=1 color=#ffffff face="Arial, Helvetica, sans-serif"> <br></font>
<a href="javascript:document.frm.submit();"><img alt="View" title="View" src=images/go.gif border=0></a></td></tr>
</table></form></td>
<td width=150> </td></tr></table></td></tr>
<tr bordercolor="#eeeeee" bgcolor="#eeeeee">
<td width="80" height="0" align="center"><strong><font size="2" face="Arial, Helvetica, sans-serif">Sun</font></strong></td>
<td width="80" height="0" align="center"><strong><font size="2" face="Arial, Helvetica, sans-serif">Mon</font></strong></td>
<td width="80" height="0" align="center"><strong><font size="2" face="Arial, Helvetica, sans-serif">Tue</font></strong></td>
<td width="80" height="0" align="center"><strong><font size="2" face="Arial, Helvetica, sans-serif">Wed</font></strong></td>
<td width="80" height="0" align="center"><strong><font size="2" face="Arial, Helvetica, sans-serif">Thur</font></strong></td>
<td width="80" height="0" align="center"><strong><font size="2" face="Arial, Helvetica, sans-serif">Fri</font></strong></td>
<td width="80" height="0" align="center"><strong><font size="2" face="Arial, Helvetica, sans-serif">Sat</font></strong></td>
</tr>
<?php
for($i=0;$i<5;$i++){
print("\n<tr>");
for($j=0;$j<7;$j++){
if(($i==0) && ($j==$FirstDayOfMonth)){
$fulldate=$month."-".$daynum."-".$year;
if($fulldate==$today){
print($td3.$daynum."<br>\n");
}else{
print($td2.$daynum."<br>\n");
}
print($etd);
}elseif((($j>$FirstDayOfMonth)||($i>0))&&($daynum<$numDaysInMonth)){
$daynum++;
$fulldate=$month."-".$daynum."-".$year;
if($fulldate==$today){
print($td3.$daynum."<br>\n");
}else{
print($td2.$daynum."<br>\n");
}
print($etd);
}else{
print($td2." </td>\n");
}
}
print("</tr>\n");
// do we have a 6th week in the month?
if(($i==4) && ($daynum<$numDaysInMonth)){
$i--;
}
if(($i==3) && ($daynum>=$numDaysInMonth)){
$i=$i+2;
}
}
print("</table><P>");
$fsmonth=date("n",mktime(0,0,0,$thisMonth+3,1,1999));
$fsyear=date("Y",mktime(0,0,0,$thisMonth+3,1,$thisYear));
print("<script language=javascript>
<!--
document.frm.aMonth.selectedIndex=".($month-1).";
document.frm.aYear.selectedIndex=".($year-2003).";
document.srcfrm.sMonth.selectedIndex=".($thisMonth-1).";
document.srcfrm.sYear.selectedIndex=".($thisYear-2003).";
document.srcfrm.eMonth.selectedIndex=".($fsmonth-1).";
document.srcfrm.eYear.selectedIndex=".($fsyear-2003).";
// -->
</script>");
?>
<!-- finish the page design code here -->
<!-- and then either print the EOB/H tags,
or put them in as HTML.-->
</body></html>