PHPでカレンダーとか死ぬほどよくありますが、mktime()とか使って手動で作ってるタイプばっかりで、DateTimeを使ったカレンダーが見当たらなかったので作ってみる。
当月や週末の判定が微妙だな。
完全にやるならDatePeriodをくるくるしたときに出てくるDateTimeを上書きしてisPresentMonth()的なメソッドを追加するか、描画系もクラス内で行えるようにしておくとよいでしょう。
ここまで作っておいてなんですが、どうしても外部ライブラリが許されざる状況にあるとかでない限りはPEAR::Calendarとかに任せとけばいいんじゃないかな。
<?php // かれんだー class Calendar{ private $datetime; public function getDatetime(){ return clone $this->datetime; } /** * コンストラクタ * @param int 年 * @param int 月 * @param int 日 */ public function __construct($year = NULL, $month = NULL, $day = NULL){ // デフォルト $default = new DateTime(); if($year ===NULL){ $year = $default->format('Y'); } if($month ===NULL){ $month = $default->format('m'); } if($day ===NULL){ $day = $default->format('d'); } // 本日 $str =sprintf('%04d-%02d-%02d', (int)$year, (int)$month, (int)$day); $this->datetime = DateTime::createFromFormat('Y-m-d', $str, new DateTimeZone('Asia/Tokyo')); if(!$this->datetime){ throw new InvalidArgumentException(); } } /** * 日曜開始、土曜終了のカレンダーを取得 * @return DatePeriod */ public function getCalendar(){ // 開始日 月初を含む週の日曜日 $start = clone $this->datetime; $start->modify('first day of')->modify('+1 day')->modify('last Sunday'); // 終了日 月末を含む週の土曜の次の日 DatePeriodは最終日が含まれないため+1する $finish = clone $this->datetime; $finish->modify('last day of')->modify('-1 day')->modify('next Saturday')->modify('+1 day'); return new DatePeriod($start, new DateInterval('P1D'), $finish); } } // インスタンス $calendar = new Calendar($_REQUEST['y'], $_REQUEST['m'], $_REQUEST['d']); // 画面表示 print('<table><tr><th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th></tr><tr>'); foreach($calendar->getCalendar() as $key=>$val){ if($val->format('w') === '0'){ // 日曜日 print('<tr><td>'); }else{ // その他 print('</td><td>'); } if($val->format('m') === $calendar->getDatetime()->format('m')){ // 当月 print($val->format('d')); }else{ // 当月ではない print(' '); } if($val->format('w') === '6'){ // 土曜日 print('</td></tr>'); } } print('</table>');2038年問題フリーで、9999年まで使えるカレンダーです。
当月や週末の判定が微妙だな。
完全にやるならDatePeriodをくるくるしたときに出てくるDateTimeを上書きしてisPresentMonth()的なメソッドを追加するか、描画系もクラス内で行えるようにしておくとよいでしょう。
ここまで作っておいてなんですが、どうしても外部ライブラリが許されざる状況にあるとかでない限りはPEAR::Calendarとかに任せとけばいいんじゃないかな。
PR