何気にマニュアルにも書いてあるのですが(http://www.php.net/manual/ja/function.mktime.php)、 mktime 関数は引数から得られる日時の妥当性を計算して、例えば 2004年の1月32日となるような値を渡してもちゃんと 2004年の2月1日 に相当する秒数を返してくれます。よく考えると当たり前のような気がしてきますが、これは便利です。
date 関数は、第二引数 (省略可能) にタイムスタンプを渡すと、それに対応した日付情報を返してくれるので、上記の mktime と組み合わせて使うと日付の計算がとても簡単になります。
print date("Y-m-d", mktime(0, 0, 0, 1, 32, 2004)) というコードは、「2004-02-01」という文字列を出力します。
また、 date の第一引数に t を指定するとその月の日数を取得できたり w や D で曜日が取得できたりと、フォーマットも多く用意されているので、うまく使えば結構遊べそうです。
ということでカレンダーで遊んでみました。割と手抜きですが (曜日は実際使うなら直書きでない方がいいでしょう) 。
function Calendar($year = 2004, $month = 1) {
$day = 1; // 一日から
$start_week = date("w", mktime(0, 0, 0, $month, $day, $year)); // 一日の曜日
print "<table summry=\"Calendar\" border=\"1\">\n";
print "<caption>{$month}月</caption>\n";
print "<tr><th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th></tr>\n";
print "<tr>";
for ($i = 0; $i < $start_week; $i++) { // 一日になるまでループ
print "<td> * </td>";
}
for ($i = 0; $i < 42 - $start_week; $i++) {
if ($day <= date("t", mktime(0, 0, 0, $month, $day, $year)))
print "<td>{$day}</td>";
else
print "<td> * </td>";
if ( (6 == date("w", mktime(0, 0, 0, $month, $day, $year))) ) {
if ($day >= date("t", mktime(0, 0, 0, $month, $day, $year))) break;
print "</tr>\n<tr>";
}
$day++;
}
print "</tr>\n";
print "</table>\n";
}
アスタリスクで埋められている部分も、ちょっといじれば先月の日付や来月の日付を挿入できますが、ここでは省略します。