プチ・スケジュール管理システム作ってみた

こんにちは、還暦女子です。

今度はスケジュール管理表を作ってみました。
お店や病院などの営業予定や出勤表、シフト表、マイスケジュール等CSSを工夫すれば色々使えるかなと思って考えました。
初めての試みがいっぱいで穴だらけのコードですが、とりあえず一通り動きました。

##作りたい仕様

+ ログイン管理内で編集、別ページのプレビューで表示
+ HTMLで入力可
+ 祝日は自由にカスタマイズ
+ 毎月自動更新
+ データベースを使わないライトな作り

##サイト設計とデザイン

![plan.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641189/9e190cee-4747-dd4c-5e83-2d4ebce6f3e8.jpeg)

AdobeXDで作成しました。
サイトデザイン以外にも設定イメージ、マニュアル、プロトタイプでプレゼンテーションも使える便利マルチツールです。書き出しは画像形式以外にもプラグインを使えばPDFも可能です。

デザインを元にHTMLとCSSのテンプレートを作成します。
今回は水色ベース。

管理画面イメージ
![write.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641189/82be4387-4a8a-8cc7-b9a9-a77de169aab6.jpeg)

プレビュー画面イメージ
![prev.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641189/b05518da-485a-4e59-04bb-fd0370f016f9.jpeg)

##カレンダー管理画面

ログインすると当月の管理画面に移行します。
tableとname属性もphpのfor文で書き出し。
Postで変数に変換するのもfor文。プログラムって一つ一つ書かなくていいから便利です。
カレンダー部分はネットに載ってるものを拾ってきてカスタマイズしました。

更新するとfile_put_contents()でjsonファイルに上書きします。
ファイル名は変数を入れてdays'.$m.'.jsonとして常に当月のjsonを取得。
jsonは1月から12月の12個のファイルを作っておき、毎年このデータを使い回す予定です。
ログインとログアウトのページは省略します。

###当月のカレンダー

```php:control.php
<?php
//当月のカレンダー
    session_start();
    session_regenerate_id(true);
    if(isset($_SESSION['login']) === false){
        echo 'ログインしていません。';
        exit();
    }

    //XSS
    function html_esc($word){
        return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
    }
    
    //トークン生成
    function getCSRFToken()
    {
        $nonce = base64_encode(openssl_random_pseudo_bytes(48));
        setcookie('XSRF-TOKEN', $nonce);
        return $nonce;
    }
    $token = getCSRFToken();
    $token = html_esc($token);
    

    date_default_timezone_set('Asia/Tokyo'); //東京時間にする
    $y = date('Y');
    $m = date('m')+0;//+intをつけないと祝日設定できない
    $week = ['日','月','火','水','木','金','土'];
    //月末の日を取得
    $lastday = date("t", mktime(0, 0, 0, $m , 1 , $y));
 
    //ファイル名は月で変動
    $file = file_get_contents('./json/days'.$m.'.json');                                     $data = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
    $array = json_decode($data,true);  


    if($_SERVER['REQUEST_METHOD'] === 'POST'){
        //postトークン追加
        function validateCSRFToken ($post_token)
        {
            return isset($_COOKIE['XSRF-TOKEN']) && $_COOKIE['XSRF-TOKEN'] === $post_token;
        }
        if(isset($_POST['csrf_token']) && validateCSRFToken($_POST['csrf_token'])){
            //OKだったら空文字でスルー
            echo '';
        } else {
            echo 'トークンが不正です。';
            exit();
        }    
        //パスをサーバーと合わせておく
        header('Access-Control-Allow-Origin: ファイルパス');
        header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
        header('X-Frame-Options: SAMEORIGIN');
        //postトークンここまで
        
        //name値をfor文で書き出し
        for($i = 0; $i < $lastday; $i++){
            $name[$i] = html_esc($_POST['name'.$i]);
        }
        
        //JSON形式に変換 
        $json = json_encode($name);
        //JSON書き出し
        //タイマー設定が作用するので前月にもデータを入れておかないと消えてしまう
        file_put_contents('./json/days'.($m-1).'.json',$json);
        file_put_contents('./json/days'.$m.'.json',$json);
        //jsonファイルを取得、valueに再代入
        $file = file_get_contents('./json/days'.$m.'.json');
        //文字コードをUTF-8に変換する
        $data = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
        $array = json_decode($data,true);
    }

?>
<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>スケジュールカレンダー管理画面 | 当月</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="format-detection" content="telephone=no">
	<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
	<link rel="stylesheet" href="common/reset.css">
	<link rel="stylesheet" href="common/style.css">
	<!--ファビコン32x32-->
	<link rel="shortcut icon" href="favicon.ico" type="image/vnd.microsoft.icon">
</head>
<body>
<div id="wrapper">
   <header id="logout" class="clearfix"><a href="logout.php">ログアウト</a></header>
   <main>
     <h1 id="title">Myカレンダー管理画面</h1>
     <div id="infoLeft">
        <div>
            <p id="ym"><?php echo $y; ?>年<span><?php echo $m; ?></span>月</p>
            <p id="next"><a href="control2.php">翌月<span class="material-icons md-24">keyboard_arrow_right</span></a></p>
            <p id="view"><a target="_blank" rel="noopener" href="schedule.php">プレビュー</a></p>
        </div>
        <p id="info">HTMLも入力できます。<br>リンクや画像も貼ってカスタマイズができます。入力後更新ボタンを押すと表示用のページに自動入力されます。変更の場合は上書きしてください。</p>
     </div>
     <form action="" method="post">
     <!-- トークンの値をvalueに -->
     <input type="hidden" name="csrf_token" value="<?php echo $token ?>">
     <table id="cale">
        <tr><?php
                foreach($week as $weeks){
                    echo '<td>'.$weeks.'</td>';
                }            
            ?>
        </tr>
        <?php
      // 1日の曜日を取得
            $wd1 = date("w", mktime(0, 0, 0, $m, 1, $y));
            // その数だけ空白を表示
            for ($i = 1; $i <= $wd1; $i++) {
            echo "<td>　</td>";
            }
 
            // 1日から月末日までの表示
            $d = 1;
            $n = 0;

            //休日を共通にしたかったので別ファイルに
            require_once(dirname(__FILE__).'/holiday.php');
            //holiday.phpで祝日設定
            for($d = 1; $d <= $lastday; $d++) {
                echo '<td class="'.$holiday[$d].'"><span class="days">'.$d.'</span><textarea class="memo" name="name'.$n.'" value="'.$array[$n].'">'.$array[$n].'</textarea></td>';
                // 今日が土曜日の場合は…
                if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) {
                    // 週を終了
                    echo "</tr>";
                    // 次の週がある場合は新たな行を準備
                    if (checkdate($m, $d + 1, $y)) {
                        echo "<tr>";
                    }
                }
                $n++;
            } 

            // 最後の週の土曜日まで移動
            $wdx = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
            for ($i = 1; $i < 7 - $wdx; $i++) {
            echo "<td>　</td>";
            }
        ?>
     </table>
     <p id="update"><input type="submit" value="更新する"></p>
     </form>
   </main>
   <footer>
       <small>Copyright 2020 All Rights Reserved. 無断転載禁止</small>
   </footer>
</div>	
</body>
</html>
```
###翌月のカレンダー

最初の月設定
$m = date('m')+1になってます。

```php:control2.php
<?php
//翌月のカレンダー
    session_start();
    session_regenerate_id(true);
    if(isset($_SESSION['login']) === false){
        echo 'ログインしていません。';
        exit();
    }

    //XSS
    function html_esc($word){
        return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
    }
    
    //トークン生成
    function getCSRFToken()
    {
        $nonce = base64_encode(openssl_random_pseudo_bytes(48));
        setcookie('XSRF-TOKEN', $nonce);
        return $nonce;
    }
    $token = getCSRFToken();
    $token = html_esc($token);
    

    date_default_timezone_set('Asia/Tokyo'); //東京時間にする
    if(date('m') === '12'){
        $y = date('Y')+1;
        $m = 1;
    } else {
        $y = date('Y');
        $m = date('m')+1;
    }
    $week = ['日','月','火','水','木','金','土'];
    //月末の日を取得
    $lastday = date("t", mktime(0, 0, 0, $m , 1 , $y));
    
    //jsonから翌月のデータ取得
    $file = file_get_contents('./json/days'.$m.'.json');                                     $data = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
    $array = json_decode($data,true);

    //翌々月に日付分の空文字設定jsonへ書き出し
    if(date('m') === '11'){//11月になったら1月をデフォルト
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, 1 , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days1.json',$file);
    } else {
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, ($m+1) , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days'.($m+1).'.json',$file);
    }

    if($_SERVER['REQUEST_METHOD'] === 'POST'){
        //postトークン追加
        function validateCSRFToken ($post_token)
        {
            return isset($_COOKIE['XSRF-TOKEN']) && $_COOKIE['XSRF-TOKEN'] === $post_token;
        }
        if(isset($_POST['csrf_token']) && validateCSRFToken($_POST['csrf_token'])){
            //OKだったら空文字でスルー
            echo '';
        } else {
            echo 'トークンが不正です。';
            exit();
        }    
        //パスをサーバーと合わせておく
        header('Access-Control-Allow-Origin: ファイルパス');
        header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
        header('X-Frame-Options: SAMEORIGIN');
        //postトークンここまで
        
        //name値をfor文で書き出し
        for($i = 0; $i < $lastday; $i++){
            $name[$i] = html_esc($_POST['name'.$i]);
        }
        
        //JSON形式に変換 
        $json = json_encode($name);
        //JSON書き出し、パーミッション変更忘れずに
        file_put_contents('./json/days'.$m.'.json',$json);

        //jsonファイルを取得、valueに再代入
        $file = file_get_contents('./json/days'.$m.'.json');
        //文字コードをUTF-8に変換する
        $data = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
        $array = json_decode($data,true);

    }

?>
<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>スケジュールカレンダー管理画面 | 翌月</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="format-detection" content="telephone=no">
	<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
	<link rel="stylesheet" href="common/reset.css">
	<link rel="stylesheet" href="common/style.css">
	<!--ファビコン32x32-->
	<link rel="shortcut icon" href="favicon.ico" type="image/vnd.microsoft.icon">
</head>
<body>
<div id="wrapper">
   <header id="logout" class="clearfix"><a href="logout.php">ログアウト</a></header>
   <main>
     <h1 id="title">Myカレンダー管理画面</h1>
     <div id="infoLeft">
        <div>
            <p id="ym"><?php echo $y; ?>年<span><?php echo $m; ?></span>月</p>
            <p id="next"><a href="control.php">当月<span class="material-icons md-24">keyboard_arrow_right</span></a></p>
            <p id="view"><a target="_blank" rel="noopener" href="schedule2.php">プレビュー</a></p>
        </div>
        <p id="info">HTMLも入力できます。<br>リンクや画像も貼ってカスタマイズができます。入力後更新ボタンを押すと表示用のページに自動入力されます。変更の場合は上書きしてください。</p>
     </div>
     <form action="" method="post">
     <!-- トークンの値をvalueに -->
     <input type="hidden" name="csrf_token" value="<?php echo $token ?>">
     <table id="cale">
        <tr><?php
                foreach($week as $weeks){
                    echo '<td>'.$weeks.'</td>';
                }            
            ?>
        </tr>
        <?php
      // 1日の曜日を取得
            $wd1 = date("w", mktime(0, 0, 0, $m, 1, $y));
            // その数だけ空白を表示
            for ($i = 1; $i <= $wd1; $i++) {
            echo "<td>　</td>";
            }
 
            // 1日から月末日までの表示
            $d = 1;
            $n = 0;

            //休日を共通にしたかったので別ファイルに
            require_once(dirname(__FILE__).'/holiday.php');
            //holiday.phpで祝日設定
            for($d = 1; $d <= $lastday; $d++) {
                echo '<td class="'.$holiday[$d].'"><span class="days">'.$d.'</span><textarea class="memo" name="name'.$n.'" value="'.$array[$n].'">'.$array[$n].'</textarea></td>';
                // 今日が土曜日の場合は…
                if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) {
                    // 週を終了
                    echo "</tr>";
                    // 次の週がある場合は新たな行を準備
                    if (checkdate($m, $d + 1, $y)) {
                        echo "<tr>";
                    }
                }
                $n++;
            } 

            // 最後の週の土曜日まで移動
            $wdx = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
            for ($i = 1; $i < 7 - $wdx; $i++) {
            echo "<td>　</td>";
            }
        ?>
     </table>
     <p id="update"><input type="submit" value="更新する"></p>
     </form>
   </main>
   <footer>
       <small>Copyright 2020 All Rights Reserved. 無断転載禁止</small>
   </footer>
</div>	
</body>
</html>
```

##カレンダープレビュー画面

ここは管理画面と作りはほぼ一緒。file_get_contents()でjsonからデータを取得してます。
翌月の方は省略します。

```php:schedule.php
<?php
    date_default_timezone_set('Asia/Tokyo'); //東京時間にする
    $y = date('Y');
    $m = date('m')+0;
    $week = ['日','月','火','水','木','金','土'];
    $lastday = date('t', mktime(0, 0, 0, $m, 1, $y));
    
    //json取得
    $file = file_get_contents('./json/days'.$m.'.json');                                     $data = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
    $array = json_decode($data,true);
    
    //デコード
    function decode_html($word){
        return html_entity_decode($word);
    }

?>
<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>スケジュールカレンダー | 当月</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="format-detection" content="telephone=no">
	<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
	<link rel="stylesheet" href="common/reset.css">
	<link rel="stylesheet" href="common/style.css">
	<!--ファビコン32x32-->
	<link rel="shortcut icon" href="favicon.ico" type="image/vnd.microsoft.icon">
</head>
<body>
<div id="wrapper">
<header id="frontHeader">
    <h1 id="title">Myカレンダー予定表</h1>
    <p>管理画面から書き出されたものが表示されています。</p>
</header>
<main id="scheduleMain">
    <h2 id="ym"><?php echo $y; ?>年<span><?php echo $m; ?></span>月</h2>
    <p id="next"><a href="schedule2.php">翌月<span class="material-icons md-24">keyboard_arrow_right</span></a></p>
    <table id="cale">
        <tr>
            <?php
                foreach($week as $weeks){
                    echo '<td>'.$weeks.'</td>';
                }       
            ?>
        </tr>
        <tr>
        <?php
            // 1日の曜日を取得
            $wd1 = date('w', mktime(0, 0, 0, $m, 1, $y));
            // その数だけ空白を表示
            for ($i = 1; $i <= $wd1; $i++) {
                echo "<td>　</td>";
            }
            // 1日から月末日までの表示
            $d = 1;
            $n = 0;
            //当月用休日設定
            require_once(dirname(__FILE__).'/holiday.php');
            //holiday.phpで祝日$holiday設定
            for($d = 1; $d <= $lastday; $d++){
                echo '<td class="'.$holiday[$d].'"><span class="days">'.$d.'</span><div class="memoUp">'.decode_html($array[$n]).'</div></td>';
                if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) {
                    // 週を終了
                    echo "</tr>";
                    // 次の週がある場合は新たな行を準備
                    if (checkdate($m, $d + 1, $y)) {
                        echo "<tr>";
                    }
                }
                $n++;
            }
            // 最後の週の土曜日まで空欄を作る
            $wdx = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
            for ($i = 1; $i < 7 - $wdx; $i++) {
            echo "<td>　</td>";
            }
        ?>
        </tr>
    </table>
</main>
<footer>
       <small>Copyright 2020 All Rights Reserved. 無断転載禁止</small>
   </footer>
</div>
</body>
</html>
```

##祝日の共通設定ファイル

ここは各ファイルに共通インクルードとして一つにしました。書き換えを楽にする為に。
Google APIを使うのも有りですが、独自で休日を入れたかったりローカルで編集したいので作りました。
毎年手書きで更新する必要がありますが。。。

※holiday.phpを@akebi_mhさんVer.に書換えました。

```php:holiday.php
//祝日の配列1
$holiday = [];
for(; $d <= $lastday; $d++) {
    $holiday[$d] = in_array($d, [
         1 => [1, 11],
         2 => [11, 23],
         3 => [20],
         4 => [29],
         5 => [3, 4, 5],
         6 => [],
         7 => [19],
         8 => [11],
         9 => [20, 23],
        10 => [11],
        11 => [3, 23],
        12 => [],
    ][(int) $m]) ? 'holiday' : 'none';
}
```

##とりあえず作ってみて思ったこと

簡単なシステムでも、一つの形になるものを作るのってすごく難しいですね。
ほんの少し操作性がいいものを追加しようとすると2、3日は軽く悩む。
今までのコードは全て捨てて、新しく作り変えることも少なくないです。
まだまだ初心者なので知らないこともいっぱいあるし。

でも動いた時の感動は恐悦至極。これがあるからやめられない。
そろそろクラスやフレームワークも触ってみたいし、DBも挑戦してみようかななどと思っています。

##追記タイマー修正

月が変わって見てみると、まあまあの失敗。
9月は希望どうりの空欄になりましたが、8月は7月の予定がまるまる移動していました。
それでもって8月に書き込んでいた予定は消滅していた…

コードを見ると、それもそのはず。
8月に書き込んでいた予定は7月の内容に上書きされてしまったんですね。。。

control.phpとcontrol2.phpには読み込むデータは変数を入れているので、月が変われば合わせてデータも変わるようになっていました。
<code>$m = date('m')+0;
$file = file_get_contents('./json/days'.$m.'.json');</code>

control2.phpは翌月のデフォルト設定もある。

```php:control2.php
    if($m === 12){
        $y = date('Y')+1;
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, 1 , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days1.json',$file);
    } else {
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, ($m+1) , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days'.($m+1).'.json',$file);
    }
```

もしくは@akebi_mhさんからアドバイスしてもらったコードをアレンジして入れてみる。

```php:control2.php
if($m === 12){
        file_put_contents('./json/days1.json', json_encode(array_fill(0, 31, '')));
    } else {
        file_put_contents('./json/days'.($m+1).'.json', json_encode(array_fill(0, 31, '')));
    }
```
全て31日分の要素になりますがコードは短くなります。

<b>なのでtimer.phpは不要になるはず!</b>

もっとシンプルに考えれば良かったんですね。
control.phpとcontrol2.phpは自然に月が変わようになっていたのでtimer.phpはいらなかったということに。
<b>不要になったtimer.phpは下記に残しておきます。</b>
意図した用途にはならなかったけどタイマーとしては機能してたので、いずれどこかで使えるかもしれないし。

```php:timer.php
<?php
//毎月1になったら自動でカレンダーを繰越し
//当月になったら先月のデーターを移行する
function daily($num){
    $file = file_get_contents('./json/days'.($num-1).'.json');
    $data = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 
    $array = json_decode($data,true);
    $json = json_encode($array);
    file_put_contents('./json/days'.$num.'.json',$json);
}

//年初めの時
function start_daily($num){
    $file = file_get_contents('./json/days12.json');
    $data = mb_convert_encoding($file, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 
    $array = json_decode($data,true);
    $json = json_encode($array);
    file_put_contents('./json/days'.$num.'.json',$json);
}

if(strtotime(date('Y-01-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-02-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    start_daily(1);
    
} elseif (strtotime(date('Y-02-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-03-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(2);
    
} elseif (strtotime(date('Y-03-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-04-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(3);
    
} elseif (strtotime(date('Y-04-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-05-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(4);
    
} elseif (strtotime(date('Y-05-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-06-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(5);
    
} elseif (strtotime(date('Y-06-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-07-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(6);

} elseif (strtotime(date('Y-07-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-08-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(7);

} elseif (strtotime(date('Y-08-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-09-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(8);

} elseif (strtotime(date('Y-09-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-10-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(9);

} elseif (strtotime(date('Y-10-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-11-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(10);

} elseif (strtotime(date('Y-11-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-12-01 00:00:00')) > strtotime(date('Y-m-d H:i:s'))){
    daily(11);

} elseif (strtotime(date('Y-12-01 00:00:00')) < strtotime(date('Y-m-d H:i:s')) && strtotime(date('Y-12-31 23:59:59')) > strtotime(date('Y-m-d H:i:s'))){
    daily(12);    
}
```

と、いうことで修正したバージョンでまた月代わり状態を見ていきます。

##月更新タイマー作動してました!!

無事に月を越すことができました。
9月が当月の予定に移動、翌月は真っ白なデフォルトに。
今回は2ヶ月表示ですが、用途によっては当月のみ、若しくは3ヶ月、4ヶ月表示も。

今度の検証は「無事に年を越しているか」ですね。
年末年始に確認します。

##失敗12月の次は13月！

12月になりました。
なんと翌月は13月！
年は繰り越さないまま2020年のまま。
Warningが出て13月のjsonが無いと警告されました。

当月のcontrol.phpは異常は無いので、翌月のcontrol2.phpを見直し。
<code>$y = date('Y');
    $m = date('m')+1;</code>
ここを変える必要がありました。

**※修正後**
<code>if(date('m') === '12'){
        $y = date('Y')+1;
        $m = 1;
    } else {
        $y = date('Y');
        $m = date('m')+1;
    }</code>
12月の場合は年を次の年へ、月は1に限定。
elseの中は修正前のものを設定。

プレビュー用のschedule2.phpも直しておきます。

そしてJSON書き出し設定も修正。

※修正前
<code>if($m === 12){
        $y = date('Y')+1;
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, 1 , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days1.json',$file);
    } else {
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, ($m+1) , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days'.($m+1).'.json',$file);
    }</code>

11月になったら1月のjsonをデフォルトにします。
修正前は12月になったら1月を白紙にしてしまいました。。。

**※修正後**
<code>if(date('m') === '11'){
        $y = date('Y')+1;
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, 1 , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days1.json',$file);
    } else {
        $days = [];
        for($i= 0; $i < date("t", mktime(0, 0, 0, ($m+1) , 1 , $y)); $i++){
            $days[$i] = '';
        }
        $file = json_encode($days);
        file_put_contents('./json/days'.($m+1).'.json',$file);
    }</code>

でもここは、前に@akebi_mhさんから教えてもらったコードの方がスッキリするかも。
全部31個分のインデックスができるけど、HTMLで日付の書出しを制御しているので問題無いかと。

<code>if($m === 12){
        file_put_contents('./json/days1.json', json_encode(array_fill(0, 31, '')));
    } else {
        file_put_contents('./json/days'.($m+1).'.json', json_encode(array_fill(0, 31, '')));
    }</code>

ちょっと考えれば、おかしいと思われているところを間違えていますね。ロジックの建て方が穴だらけなのかも。
まだまだ勉強不足です。

ついでに祝日も来年用に更新しました。

###GitHubにコードをアップしました
CSSなどのファイル一式をGitHubに公開しました。
[https://github.com/mugikomugi/calender.git](https://github.com/mugikomugi/calender.git)