HOME -> プログラム -> PHP Script -> PHP 実践-1 -> PHP 実践 カレンダー

PHP 実践 カレンダー

そんなもの携帯のカレンダーでも見ればいいんじゃないの? と言われそうですが、カレンダーは応用範囲が結構広いです。 例えば掲示板のようなものと連動させれば日記にもなるし、 或いは予約テーブルみたいなものも作れます。 カレンダー単体ではあまりありがたみもありませんが、他の機能と組み合わせる事で出来る事は何倍にも広がります。 ですのでここで簡易カレンダーを作成してみたいと思います。
 なを、ここで出す例はあくまで一例ですのでもっと効率のよいカレンダーの表示を追及するのも面白いと思います。

 なにわともあれ実践してみたいと思います。 ここは単純に今日の月から先三ヶ月間を表示するテキストカレンダを作成してみます。
カレンダーに必要な処理は何でしょうか?
今日が何日(何月)だか調べる、
各月(三ヶ月分)の日数を調べる、
各月(三ヶ月分)の1日の曜日を調べる
、 画面に出力する、
 という作業になります。このあたりまでを、とりあえずやってみましょう!
<?php
$wday = array('日','月','火','水','木','金','土'); //テーブルの週表示を用意

$year_str =date('Y'); //指定年を取得
$month_str =date('m'); //指定月を取得
for($li=0;$li < 3;$li++){ //表示の三ヶ月分をループで処理
	$nextmonth_str = $month_str + 1; //指定来月を取得
	if($nextmonth_str > 12){ //12月を超える場合は来年に持越し
		$nextmonth_str = 1; //1月にする
		$nextyear_str = $year_str +1; //年を持越す
	}else{ //12月を超えない場合は年は同年
		$nextyear_str = $year_str;
	}
	//指定月の1日
	$thisdata_str = "$year_str/$month_str/1";
	//指定来月の1日
	$nextdata_str = "$nextyear_str/$nextmonth_str/1";
	//指定月1日の1970年からの経過秒数
	$this_mstr= date('U',strtotime($thisdata_str));
	//指定来月1日の1970年からの経過秒数
	$next_mstr= date('U',strtotime($nextdata_str));
	//日数を取得
	$daycount = ($next_mstr - $this_mstr)/(60*60*24);
	//指定月の1日目の曜日を番号で取得
	$week_v = date('w',strtotime("$year_str/$month_str/1"));

	echo "<br><b> $year_str 年 $month_str 月 </b><br>";
	echo "<table border='1'><tr>"; //カレンダー週表示部分
	for($i=0;$i<=6;$i++){
		echo "<th width='36' bgcolor='#99FFCC'>"
			.$wday[$i]."</th>";
	}
	echo "</tr><tr align='right'>";
	$d = 0;
	for($i=0;$i<42;$i++){ //日数描画部分
		if($d >= $daycount){
			break; //指定月の日数を越えたらループを抜ける
		}
		if($i < $week_v){
			echo "<td> </td>"; //1日以前はエスケープ
		}else{
			$d++;
			echo "<td>$d</td>"; //日付を表示
		}//END_else_if
		if(($i % 7)==6){
			echo "</tr><tr align='right'>";
		}
	}//END_for
	echo "</table>";

	$month_str ++; //月を繰上げる
	if($month_str > 12){ //12月を超える場合は来年に持越し
		$month_str = 1; //1月にする
		$year_str ++; //年を持越す
	}
}//END_for
?>
 ここでは今月から三ヶ月分先だけ表示表示していますが、 2行目、3行目で好みの年月を指定すれば任意の月のカレンダーを取得できますし、 三ヶ月分をループで処理、という部分を3から任意の数値にすれば何ヶ月分のカレンダーでも取得できます。
 ここでのキモは date() 関数でタイムスタンプを取得しているところです。 これは Perl でなら localtime()で取得します。 1970年からの経過秒数を取得できますが、これから計算して指定月の日数を求めています。 あとは何曜日から始まるかが分かればおのずとカレンダーが完成します。 指定月の1日が何曜日かも date() 関数で取得が可能です。指定月の1日目の曜日を番号で取得、という部分がそれに当たります。 上記のコードは一週間での折り返しカレンダーとなっていますが、 日付を描画、以下のループ文を変更する事で様々なカレンダー形式を出力する事ができます。
 先のコードはかなり Perl に近いものがあります。 というのも date() を localtime() に変更してあと他をちょっといじるだけでCGI/Perl環境でも動くからです。 ではもうちょっと PHP の利点を活かしたコードを書いてみる事にしましょう。 先程は指定月の日数を
$daycount = ($next_mstr - $this_mstr)/(60*60*24); //日数を取得
という部分で取得しました。これは
指定月の日数 = (1970年から指定月の来月1日までの秒数 - 1970年から指定月1日までの秒数)割る(秒x分x時間)
という方法で得ているのです。
PHPではこれを一発で取得出来る関数が用意されています。 カレンダー関数というものですが、
$thisdata_str = "$year_str/$month_str/1";
$nextdata_str = "$nextyear_str/$nextmonth_str/1";
$this_mstr= date('U',strtotime($thisdata_str));
$next_mstr= date('U',strtotime($nextdata_str));

$daycount = ($next_mstr - $this_mstr)/(60*60*24);
 というコード部分を
$daycount = cal_days_in_month(CAL_GREGORIAN,$month_str,$year_str);
 と書き換えましょう。 calender関数群はWindowsPHPであれば標準で動作しますので特段設定を必要とせずそのままコーディング可能です。 cal_days_in_month() 関数は指定カレンダーで指定年月の日数を返すという機能を持っています。 現在のカレンダーはグレゴリウス暦なので CAL_GREGORIAN の指定を行っています。 5行をこの関数一個で代用する事ができます。 PHPには色々な関数が用意されているので、色々探してみると簡単にコーディング出来る場合が多々あります。

 カレンダーには様々な利用方があります。 ここではカレンダーの一例をお見せしましたが、 ぜひ自分なりのラッピング関数みたいなものを作って様々な場面に活用してみてください!


2008年 10月 21日ドキュメント作成
2008年 12月 23日ドキュメント更新