はじめに
PHPで日付を後続の処理でパラメータとして扱う場合、選択リストから年月日を選択するケースがよくあります。選択リストに年月日をセットする場合は、「年」「月」「日」別々に3つのリストを用意するパターンもありますし、1つの選択リストで済ませる場合もあります。また、目的によっては明日以降の日付をセットしておいた方が使いやすかったり、現在の時刻を反映して選択リストの初期値がセットされていると時刻の選択がスムーズだったりします。これらのパターンについていくつか見てみましょう。
対象読者
PHPを既にお使いの方を対象としています。基本的な内容ですが、PHPに関する入門用の内容は含んでいません。必要に応じてPHPマニュアルなどのマニュアルや各書籍をご覧ください。
必要な環境
PHPがインストールされ、PHPスクリプトが動作可能な状態であることを前提としています。
日付を選択するリスト
日付をパラメータとして受け取るための簡単な例は3つの選択リストを用意して、「年、月、日」を選択させるものでしょう。生年月日などを選択させるときによく見られる構成です。これはselect
タグのoption
要素を繰り返し出力するときに、選択値たとえば、月であれば「1」から「12」を出力します。
<html> <head> <title>日付を選択するリスト</title> </head> <body> <form method="POST"> <?php echo "<select name=\"yyyy\">"; for ($i = 2005; $i < 2020; $i++) { echo "<option>".$i; } echo "</select> 年 "; echo "<select name=\"mm\">"; for ($i = 1; $i < 13; $i++) { echo "<option>".$i; } echo "</select> 月 "; echo "<select name=\"dd\">"; for ($i = 1; $i < 32; $i++) { echo "<option>".$i; } echo "</select> 日 "; echo "<p>選択された日付:".$_POST["yyyy"]. "/".$_POST["mm"]."/".$_POST["dd"]; ?> <p><input type="submit" value="送信"> <form> </body> </html>
明日以降の日付をセットする
日付を選択させるリストでも、商品の配達希望日のように特定の日付、たとえば明日以降を選択させたい場合があります。前述の単純な選択リストを使っても可能ですが、次の例ではより単純に日付を選択できるようにdate
関数を使って明日以降の日付を選択リストにセットします。明日の日付として、strtotime
関数に渡すパラメータで「+1 day
」を使うことができ、「+1」を増やしていくことで明日以降の日付を選択リストに出力しています。
<html> <head> <title>明日以降の日付をセットする</title> </head> <body> <form method="POST"> <?php echo "今日の日付:".date("Y/m/d"); echo "<p><select name=\"selDate\">"; for ($i = 1; $i < 5; $i++) { echo "<option>".date("Y/m/d", strtotime("+$i day")); } echo "</select>"; echo "<p>選択された日付:".$_POST["selDate"]; ?> <p><input type="submit" value="送信"> <form> </body> </html>
前後の月へのリンクを表示する
現在を基準にした日付を選択させる例は他にもいくつかあります。ブログなどでは表示する記事を月単位で絞り込めるように前月や来月へのリンクも見られます。これも次のようにdate
関数を使って前月から3ヶ月分のリンクを作成することで実現します。
<html> <head> <title>前後の月へのリンクを表示する</title> </head> <body> <?php //年月を取得する if (isset($_GET["ym"])) { $yyyy = substr($_GET["ym"], 0, 4); $mm = substr($_GET["ym"], 5, 2); } else { $yyyy = date("Y"); $mm = date("m"); } //前後の年月へのリンク表示文字列 $ym = date("Y/m", mktime(0, 0, 0, $mm, 1, $yyyy)); $ar_name = array("<前", $ym, "次>"); //前後の年月へのリンクを表示する for ($i = 0; $i < 3; $i++) { $ym = date("Y/m", mktime(0, 0, 0, $mm + $i-1, 1, $yyyy)); echo "<a href=". $_SERVER["PHP_SELF"] ."?ym=$ym>$ar_name[$i]</a> "; } echo "<p>選択された日付:".$_GET["ym"]; ?> </body> </html>
有効な月末日までをセットする
1日から月末の日付までを選択リストにセットする場合、各月によって異なる末日への対応が必要です。月末日付のテーブルを用意しておく方法もありますが、うるう年の対応などが面倒です。有効な日付を判別するcheckdate
関数を使って、関数の戻り値がTRUE
である時は日付を出力するようにすると、指定年月の最終日となる日付までを出力させることができます。
<html> <head> <title>有効な末日までを選択リストにセット</title> </head> <body> <form method="POST"> <?php $yyyy = 2005; $mm = 2; $dd = 1; //日付をセット echo "<select name=\"ymd\">"; while (checkdate($mm, $dd, $yyyy)) { echo "<option>".$yyyy."/".$mm."/".$dd; $dd += 1; } echo "</select>"; //選択された日付を表示 echo "<p>選択された日付:".$_POST["ymd"]; ?> <p><input type="submit" value="送信"> <form> </body> </html>
予約時刻をセットする
予約時刻の選択などのように、一定間隔の時刻を選択リストに出力したいこともあります。date
関数で時間(hour
)を一定間隔で加算していくことで、このような選択リストが作成可能です。
<html> <head> <title>予約時刻をセットする</title> </head> <body> <form method="POST"> <?php echo "<select name=\"selTime\">"; for ($i = 9; $i < 18; $i++) { echo "<option>".date("Y/m/d G:00", strtotime("+$i hour")); } echo "</select>"; echo "<p>選択された時間:".$_POST["selTime"]; ?> <p><input type="submit" value="送信"> <form> </body> </html>
一定間隔の時間をセットする
時間を選択リストにセットするときに、1時~11時や1分~59分といった具合に1時間単位や1分刻みで値をセットするのではなく、15分間隔といった具合に一定間隔で選択リストにセットしたいこともあります。この場合はstrtotime
関数で「minute
」を加算しながらdate
関数で時間をセットしていきます。
<html> <head> <title>時間を一定間隔で選択リストにセット</title> </head> <body> <form method="POST"> <?php //時間をセット echo "<select name=\"selTime\">"; for ($i = 0; $i < 96; $i++) { echo "<option>".date("H:i", strtotime("+". $i * 15 ." minute")); } echo "</select>"; //選択された時間を表示 echo "<p>選択された時間:".$_POST["selTime"]; ?> <p><input type="submit" value="送信"> <form> </body> </html>
現在の時間を選択リストの初期値に反映する
前述のように一定間隔の時間がセットされた選択リストは、初期値に現在の時間を反映させたいことがあります。この場合は、選択リストにセットする時間と、現在の時間を比較しながら大小条件を満たす時に「selected
」を出力します。これにより、現在の時間に最も近い要素が最初から選択状態となります。これは、タイムカードで現在の時間と近い要素を選択することが想定されるケースなどに使えます。
<html> <head> <title>現在の時間を選択リストの初期値に反映</title> </head> <body> <form method="POST"> <?php //時間間隔を設定 $stepTime = 15; //時間をセット echo "<select name=\"selTime\">"; for ($i = 0; $i < 96; $i++) { $dispTime = date("H:i", strtotime("+". $i * $stepTime . " minute")); $now = date("H:i"); echo "<option"; if ($now >= $dispTime and $dispTime + $stepTime > $now) { echo " selected "; } echo ">" . $dispTime; } echo "</select>"; //現在の時間を表示 echo "<p>現在の時間:".$now; //選択された時間を表示 echo "<p>選択された時間:".$_POST["selTime"]; ?> <p><input type="submit" value="送信"> <form> </body> </html>
入力時刻を処理する
時刻を選択させるのではなく、4桁で入力してもらう場合もあります。この場合は受け取った時刻のチェックと整形が必要となります。次の例では入力時刻をsubstr
関数で分割して範囲をチェックしています。
<html> <head> <title>入力時刻を処理する</title> </head> <body> <form method="POST"> <?php //入力時刻を受け取る $strDate = $_POST["txtDate"]; //入力時刻をチェックする if (strlen($strDate) < 4) { $strErr = "4桁で入力してください。"; } else { $mm = substr($strDate, 0, 2); $ss = substr($strDate, 2, 2); if ($mm < "00" or $mm > "24") { $strErr = "時間が範囲外です。"; } if ($ss < "00" or $ss > "60") { $strErr = "分が範囲外です。"; } } //チェック結果を表示する if (isset($strErr)) { echo "<p>エラー:$strErr"; } else { echo "<p>入力値:$mm 時 $ss 分"; } ?> <p><input type="text" name="txtDate" value="<?= $strDate ?>"> <p><input type="submit" value="送信"> <form> </body> </html>
カレンダーを表示する
カレンダーのサンプルです。ここまでで説明した前後の年月へのリンクやcheckdate
関数による有効月末日付の判別も使っています。日曜日を新たな行で始めるため、「date("w", ...)
」の戻り値が「0」だったときにtr
タグを追加しています。
<html> <head> <title>カレンダー</title> </head> <body> <?php //年月を取得する if (isset($_GET["ym"])) { $yyyy = substr($_GET["ym"], 0, 4); $mm = substr($_GET["ym"], 5, 2); } else { $yyyy = date("Y"); $mm = date("m"); } //前後の年月へのリンク表示文字列 $ym = date("Y/m", mktime(0, 0, 0, $mm, 1, $yyyy)); $ar_name = array("<前", $ym, "次>"); //前後の年月へのリンクを表示する for ($i = 0; $i < 3; $i++) { $ym = date("Y/m", mktime(0, 0, 0, $mm + $i-1, 1, $yyyy)); echo "<a href=\"test.php?ym=$ym\">$ar_name[$i]</a> "; } //曜日を表示する echo "<table border=\"1\">"; echo "<tr>"; echo "<td>日</td>"; echo "<td>月</td>"; echo "<td>火</td>"; echo "<td>水</td>"; echo "<td>木</td>"; echo "<td>金</td>"; echo "<td>土</td>"; echo "</tr>"; //日付表示を開始する echo "<tr>"; $dd = 1; //1日の曜日まで移動する $firstw = date("w", mktime(0, 0, 0, $mm, 1, $yyyy)); for ($i = 0; $i < $firstw; $i++) { echo "<td></td>"; } //日付を表示する while (checkdate($mm, $dd, $yyyy)) { if (date("w", mktime(0, 0, 0, $mm, $dd, $yyyy)) == 0) { echo "</tr><tr>"; } echo "<td>$dd</td>"; $dd += 1; } echo "</tr></table>"; ?> </body> </html>
まとめ
本稿では、処理で使う日付や時間の扱いに関して次のようなポイントを説明しました。
date
関数とstrtotime
関数によって表示する日時の間隔などを決定できる- テキストボックスに入力された時刻は
substr
関数で処理できる checkdate
関数で有効な月末日を調べることができる- 時刻選択リストは初期値をセットすると用途によっては便利
参考資料
- 『PHP辞典』 西沢直木 著、翔泳社、2005年1月
- 『PHPによるWebアプリケーションスーパーサンプル』 西沢直木 著、ソフトバンクパブリッシング、2002年9月