LoginSignup
21
22

More than 5 years have passed since last update.

PHPでナウいカレンダー

Last updated at Posted at 2013-12-20

PHPでカレンダーとか死ぬほどよくありますが、mktime()とか使って手動で作ってるタイプばっかりで、DateTimeを使ったカレンダーが見当たらなかったので作ってみる。

<?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(2013, 12, 20);

    // 画面表示
    print('<table><tr><th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th></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('&nbsp;');
        }

        if($val->format('w') === '6'){
            // 土曜日
            print('</td></tr>');
        }
    }
    print('</table>');

2038年問題フリーで、9999年まで使えるカレンダーです。

当月や週末の判定が微妙だな。
完全にやるなら月比較メソッドを追加するか、むしろ描画系もクラス内で行えるようにしておくとよいでしょう。

ここまで作っておいてなんですが、どうしても外部ライブラリが許されざる状況にあるとかでない限りはPEAR::Calendarとかに任せとけばいいんじゃないかな。

21
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
22