LoginSignup
1
4

More than 3 years have passed since last update.

PHPとjavascriptで営業日カレンダー

Last updated at Posted at 2020-02-27

phpとjavascriptで営業カレンダーを作る

完成した表示
スクリーンショット 2020-02-27 9.32.01.png
仕様
・休みは赤色にする
・定休日:祝日と日曜、木曜
・アイコンクリックで表示月変更

設計
・PHPでカレンダーを構築する配列をJSONで出力
・ajaxで受け取り出力する。

1.祝日配列のつくる

内閣府のページに祝日のcsvがあるので、そこからダウンロードする。
https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html
※csvはUTF-8に変換して保存。

calendar.php
function get_public_holidays(){
    $path = "./syukujitsu.csv";
    $csv = new SplFileObject($path);
    $csv->setFlags(SplFileObject::READ_CSV);
    $holidays = [];
    foreach ($csv as $key => $line){
        $holidays[$line[0]] = $line[1];
    }
    return $holidays;
}

2.カレンダーを構築する配列をつくる

calendar.php
function make_date_list($year,$month){

    $regular_holiday = [0,4]; //定休日:曜日
    $public_holidays = get_public_holidays(); //祝日

    $target = new \DateTime("{$year}-{$month}-01");
    $date = [];
    for($i = 0; $i < intval($target->format('t')); $i++){

        if($i > 0) $target->modify('+1day');
        //祝日
        if(isset($public_holidays[$target->format('Y/n/d')])){
            $holiday = true;
        //定休日
        }else if(in_array($target->format('w'),$regular_holiday)){
            $holiday = true;
        }else{
            $holiday = false;
        }

        $dates[$i] = [
            'day' => $target->format('d'),
            'week' => $target->format('w'),
            'holiday' => $holiday,
        ];

    }

    /*カレンダーの空欄箇所*/
    $first_date = current($dates);
    $end_date = end($dates);

    $damy_num = intval($first_date['week']);
    if($damy_num > 0){
        $damy = [];        
        for($i = $damy_num - 1;0 <= $i;$i--){
            array_unshift($dates,['week'=>$i,'day'=>'&nbsp;']);
        }    
    }

    $damy_num = intval($end_date['week']);
    if($damy_num < 6){
        $damy = [];        
        for($i = $damy_num; $i < 6;$i++){
            array_push($dates,['week'=>$i,'day'=>'&nbsp;']);
        }
    }

    return $dates;
}

3.リクエストがよる出力

calendar.php
if(isset($_GET['y']) and $_GET['y']){
    $year = $_GET['y'];
}else{
    $year = date('Y');
}

if(isset($_GET['m']) and $_GET['m']){
    $month = $_GET['m'];
}else{
    $month = date('m');
}

$dates = make_date_list($year,$month);

echo json_encode($dates);

4.javascriptでのカレンダー構築

2ヶ月先までの表示にしています。

calendar.js

var nowDate;
var year;
var month;

$(function(){
    nowDate = new Date();
    year = nowDate.getFullYear(); // 年
    month = nowDate.getMonth() + 1; // 月

    MakeCalendar();
});

function prev(){
    if(month === 1){
        month = 12;
        year--;
    }else{
        month--;
    }
    MakeCalendar();

}

function next(){
    if(month === 12){
        month = 1;
        year++;
    }else{
        month++;
    }
    MakeCalendar();
}

function MakeCalendar(){
    $.ajax({
        url: 'calender.php?y='+year+'&m='+month,
        dataType: 'json',
        timeout: 10000,  
        success: function(json) {

            var c = '<div class="cal"><div class="cal_header">';
            if(nowDate.getFullYear() <= year && (nowDate.getMonth() + 1) < month ){
                c += '<a href="" onClick="prev();return false;" class="cal_prev"><img src="./images/cal_prev.png" alt="前の月" width="19"></a>';
            }else{}

            if(nowDate.getFullYear() >= year && (nowDate.getMonth() + 3) > month ){
                c += '<a href="" onClick="next();return false;" class="cal_next"><img src="./images/cal_next.png" alt="次の月" width="19"></a>'
            }else{}

            c += '<strong>'+year+''+month+'月</strong>';
            c += '</div>';
            c += '<div class="cal_body">';
            c += '<table class="table_cal">';
            c += '<thead><tr><th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th></tr></thead>';

            jQuery.each(json, function(i, date) {

                if(date.week === '0'){
                    c += '<tr>';
                }else{}
                if(date.holiday === true){
                    c += '<td><span class="closed">'+date.day+'</span></td>';
                }else{
                    c += '<td>'+date.day+'</td>';
                }

                if(date.week === '6'){
                    c += '</tr>';
                }else{}

            });

            c += '</tbody></table></div></div>';

            $('#calendar').html(c);

        },
         error: function(xhr, textStatus, error) {
            alert('ERR');
        }
    });

}

4.表示

表示する箇所にタグとCSSを構築して完成。

sample.html

<div id="calendar"></div>

sample.css

.cal{background:#fff;box-shadow:2px 2px 4px rgba(0,0,0,0.2);}
.cal_header{padding:15px 13px;border-bottom:1px solid #ddd;}
.cal_header a,.cal_header span{display:block;}
.cal_header strong{display:block;text-align:center;font-size:1.3rem;color:#005ca2;line-height:19px;}
.cal_prev{float:left;cursor:pointer;}
.cal_next{float:right;cursor:pointer;}
.cal_body{padding:10px 15px;text-align:center;}

.table_cal{width:100%;border-collapse:collapse;}
.table_cal th,.table_cal td{font-size:1.1rem;text-align:center;height:30px;min-width:31px;}

.today{font-weight:bold;text-decoration:underline;}
.closed{display:inline-block;width:22px;height:22px;background:#eb6e8f;color:#fff;border-radius:50%;line-height:23px;}

.cal_bottom{font-size:1.1rem;margin:10px 0 15px;}
.cal_bottom span{vertical-align:middle;margin-right:4px;}

1
4
0

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
1
4