@ PHP

Calendar:カレンダーの生成

カレンダーは、スケジュール管理や予約などの web アプリケーションを作る場合に欠かせないロジックです。

日付を扱う date() 関数と日付 / 時刻の値からタイムスタンプを取得する mktime() を利用して、今月のカレンダーを作ってみましょう。

今月の1日から末日までの表示

今日の日付を 2016年2月1日と仮定して、1日から末日までを表示します。

checkdate() メソッドは、引数で指定された日付の妥当性をチェックし、各パラメータが適切に指定されている場合に、妥当であると判断し true を返します。

calendar01.php

<?php
$y = 2016;
$m = 2;
$d = 1;

// 今月の1日から末日までの表示
while (checkdate($m, $d, $y)) {
    echo $d;
    $d++;
}

テーブルのセルの中に日付を表示する。

データセル <td> 内に日付が出力されるように HTML を記述します。

calendar02.php

<table border="1">
  <tr>
<?php
$y = 2016;
$m = 2;
$d = 1;

// 今月の1日から末日までの表示をテーブルに格納
while(checkdate($m, $d, $y)) {
    echo "<td>$d</td>";
    $d ++;
}
?>
  </tr>
</table>

土曜日で改行する

mktime() メソッドで年月日を取得し、date(“w”) が6(土曜日)と等しい場合は、</tr> を出力してテーブルの行を終了。

さらに、$d + 1 の妥当性をチェックし、次の日が存在する場合 <tr> を出力して新たな行を準備します。

calendar03.php

<table border="1">
  <tr>
<?php
date_default_timezone_set('Asia/Tokyo');
$y = 2016;
$m = 2;
$d = 1;

// 1日から月末日までの表示
while (checkdate($m, $d, $y)) {
    echo "<td>$d</td>";
    
    // 今日が土曜日の場合は…
    if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) {
        // 週を終了
        echo "</tr>";
        
        // 次の週がある場合は新たな行を準備
        if (checkdate($m, $d + 1, $y)) {
            echo "<tr>";
        }
    }
    $d ++;
}
?>
</table>

1日の曜日まで空白セルを出力する

毎月1日は必ずしも日曜日(左端)とは限らないので、毎月の1日の曜日番号を調べて、その位置まで空白セルを出力してして移動します。

calendar04.php

<table border="1">
  <tr>
<?php
$y = 2016;
$m = 2;
$d = 1;

// 1日の曜日を取得
$firstday = date("w", mktime(0, 0, 0, $m, 1, $y));

// その数だけ空白を表示
for ($i = 1; $i <= $firstday; $i ++) {
    echo "<td> </td>";
}

// 1日から月末日までの表示
while (checkdate($m, $d, $y)) {
    echo "<td>$d</td>";
    
    // 今日が土曜日の場合は…
    if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) {
        // 週を終了
        echo "</tr>";
        
        // 次の週がある場合は新たな行を準備
        if (checkdate($m, $d + 1, $y)) {
            echo "<tr>";
        }
    }
    $d ++;
}

// 最後の週の土曜日まで移動
$lastday = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
for ($i = 1; $i < 7 - $lastday; $i ++) {
    echo "<td> </td>";
}
?>
</table>

カレンダーの年月を現在の年月にする

年月を示す$y、$mには固定値が入っているので、現在の年月を表示するように変更します。

calendar05.php

<table border="1">
  <tr>
    <th>日</th>
    <th>月</th>
    <th>火</th>
    <th>水</th>
    <th>木</th>
    <th>金</th>
    <th>土</th>
  </tr>
  <tr>
<?php
$y = date('Y');
$m = date('m');
$d = 1;

// 1日の曜日を取得
$firstday = date("w", mktime(0, 0, 0, $m, 1, $y));

// その数だけ空白を表示
for ($i = 1; $i <= $firstday; $i ++) {
    echo "<td> </td>";
}

// 1日から月末日までの表示
while (checkdate($m, $d, $y)) {
    echo "<td>$d</td>";
    
    // 今日が土曜日の場合は…
    if (date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) {
        
        // 週を終了
        echo "</tr>";
        
        // 次の週がある場合は新たな行を準備
        if (checkdate($m, $d + 1, $y)) {
            echo "<tr>";
        }
    }
    $d ++;
}

// 最後の週の土曜日まで移動
$lastday = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
for ($i = 1; $i < 7 - $lastday; $i ++) {
    echo "<td> </td>";
}
?>
</table>

現在の年月は、getdate() メソッドで取得することもできます。

example.php

<?php
$today = getdate();
$y = $today['year'];
$m = $today['mon'];
$d = 1;
?>

日付リンクを表示する

スケジュール管理や予約などの web アプリケーションでは、カレンダーの日付をクリックして登録画面に移動する方法がよく使われます。そのために必要なリンクを表示します。

calendar06.php

<table border="1">
  <tr>
    <th>日</th>
    <th>月</th>
    <th>火</th>
    <th>水</th>
    <th>木</th>
    <th>金</th>
    <th>土</th>
  </tr>
  <tr>
<?php
$y = date('Y');
$m = date('m');
$d = 1;

// 1日の曜日を取得
$firstday = date("w", mktime(0, 0, 0, $m, 1, $y));

// その数だけ空白を表示
for($i = 1; $i <= $firstday; $i ++) {
  echo "<td> </td>";
}

// 1日から月末日までの表示
while(checkdate($m, $d, $y)) {
  // 日付リンクの表示
  $link = "schedule.php?ymd=%04d%02d%02d";
  print "<td><a href=\"" . sprintf ( $link, $y, $m, $d ) . "\">{$d}</a></td>";

  // 今日が土曜日の場合は…
  if(date("w", mktime(0, 0, 0, $m, $d, $y)) == 6) {
    // 週を終了
    echo "</tr>";

    // 次の週がある場合は新たな行を準備
    if(checkdate($m, $d + 1, $y)) {
      echo "<tr>";
    }
  }
  $d ++;
}

// 最後の週の土曜日まで移動
$lastday = date("w", mktime(0, 0, 0, $m + 1, 0, $y));
for($i = 1; $i < 7 - $lastday; $i ++) {
  echo "<td> </td>";
}
?>
</table>