最終更新日:
公開日:
レシピ
日付・時刻
カレンダーを作成する
時刻に関連した関数を使って、指定した「年」のカレンダーを作成する方法について解説します。
この記事のポイント
- 1年分のカレンダーを表示する
- strtotime関数、mktime関数、date関数の3種類の関数を使う
- 閏年にも対応
目次
PHPでカレンダーを作成する
時刻関連の処理を行うstrtotime関数、mktime関数、date関数を使うと、手軽にカレンダーを作成することができます。
こちらのカレンダーを表示するコードは次のようになります。
コード例
<?php
//------------------------------
// カレンダーを作成する
//------------------------------
// カレンダーを表示する「年」を指定する
$year = 2019;
// 年始のタイムスタンプを取得
$timestamp = strtotime("{$year}-01-01 00:00:00");
$weekday = 0;
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>カレンダーを作成する</title>
<style>
main {
display: flex;
flex-wrap: wrap;
}
table {
margin-right: 10px;
margin-bottom: 20px;
border: 1px solid #555;
}
table caption {
padding: 7px 0;
font-size: 86%;
color: #fff;
line-height: 1.0em;
background: #555;
}
table th,
table td {
padding: 0 5px;
font-size: 86%;
color: #222;
text-align: center;
}
table td {
text-align: right;
}
</style>
</head>
<body>
<main>
<?php for( $i=1; $i<=12; $i++): ?>
<table>
<caption><?php echo $i; ?>月</caption>
<thead>
<tr>
<th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th>
</tr>
</thead>
<tbody>
<?php
// 開始日を取得
$start_day_timestamp = mktime(0,0,0,$i,1,$year);
// 末日を取得
$end_day_timestamp = mktime(0,0,0,($i+1),0,$year);
$end_day = date("d", $end_day_timestamp);
for( $j=1; $j <= $end_day; $j++ ) {
if( $j === 1 ) {
echo '<tr>';
$weekday = date("w", $start_day_timestamp);
for( $k=0; $k<$weekday; $k++ ) {
echo '<td></td>';
}
}
echo '<td>'.$j.'</td>';
$weekday++;
if( 6 < $weekday ) {
echo '</tr><tr>';
$weekday = 0;
}
}
?>
</tbody>
</table>
<?php endfor; ?>
</main>
</body>
</html>
PHPのコードだけでなくHTMLとCSSも含むため少し長くなりますが、順に解説をしていきます。
大まかな流れは下記の通りです。
- 表示する「年」を設定
- HTMLの開始
- for文で「月」ごとにカレンダーを表示
- CSSの記述
表示する「年」を設定
コード例
<?php
//------------------------------
// カレンダーを作成する
//------------------------------
// カレンダーを表示する「年」を指定する
$year = 2019;
// 年始のタイムスタンプを取得
$timestamp = strtotime("{$year}-01-01 00:00:00");
$weekday = 0;
?>
まず、最初に$yearへカレンダーを表示したい「年」を設定します。
コード例では「2019」とします。
続いて、strtotime関数で年始のタイムスタンプを取得しています。
このタイムスタンプがカレンダーの起点です。
その下の$weekdayは週の曜日を保持するための変数です。
PHPの処理では曜日について、日(0)、月(1)、火(2)、水(3)、木(4)、金(5)、土(6)と対応しているため、まずは「0」をセットします。
ここまででPHPの初期設定は完了です。
HTMLの開始
続いて、HTMLコードが始まります。
コード例
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>カレンダーを作成する</title>
<style>
// CSSを記述
</style>
</head>
<body>
<main>
// カレンダーを表示するコードを記述
</main>
</body>
</html>
HTMLは表示の「枠」になります。
今回は必要最低限のため非常にシンプルです。
for文で「月」ごとにカレンダーを表示
コードを上から順に読むとCSSの方が先に記述されていますが、body要素にカレンダーのHTMLがあってこそのCSSなのでカレンダー表示部分を先に解説します。
コード例
<?php for( $i=1; $i<=12; $i++): ?>
<table>
<caption><?php echo $i; ?>月</caption>
<thead>
<tr>
<th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th>
</tr>
</thead>
<tbody>
<?php
// 開始日を取得
$start_day_timestamp = mktime(0,0,0,$i,1,$year);
// 末日を取得
$end_day_timestamp = mktime(0,0,0,($i+1),0,$year);
$end_day = date("d", $end_day_timestamp);
for( $j=1; $j <= $end_day; $j++ ) {
if( $j === 1 ) {
echo '<tr>';
$weekday = date("w", $start_day_timestamp);
for( $k=0; $k<$weekday; $k++ ) {
echo '<td></td>';
}
}
echo '<td>'.$j.'</td>';
$weekday++;
if( 6 < $weekday ) {
echo '</tr><tr>';
$weekday = 0;
}
}
?>
</tbody>
</table>
<?php endfor; ?>
外側の「<?php for( $i=1; $i<=12; $i++): ?>」〜「<?php endfor; ?>」は、12ヶ月分ということで12回ループするように設定します。
続くtable要素は、まず曜日だけを出力します。
<table>
<caption><?php echo $i; ?>月</caption>
<thead>
<tr>
<th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th>
</tr>
</thead>
<tbody>
// カレンダー
</tbody>
</table>
次に、月初めと末日のタイムスタンプをそれぞれ取得します。
この2つのタイムスタンプを使い、「2019年1月1日〜2019年1月31日の間をループする」という条件式を作成していきます。
<?php
// 開始日を取得
$start_day_timestamp = mktime(0,0,0,$i,1,$year);
// 末日を取得
$end_day_timestamp = mktime(0,0,0,($i+1),0,$year);
$end_day = date("d", $end_day_timestamp);
月初めはどの日付も「1日」なので計算は必要ありませんが、末日は月によって変動があるためmktime関数が活躍します。
この関数は「日」に「0」を指定すると、先月末の日付のタイムスタンプを取得することができます。
例えば、「2019年2月28日」のタイムスタンプを取得したい場合、「2019年3月0日」をmktime関数に指定します。
mktime(0,0,0,3,0,2019);
タイムスタンプ形式のままだと処理がしづらいため、次の行で「日」のみ取得して$end_dayに入れます。
$end_day = date("d", $end_day_timestamp);
これで、月初から月末までループする準備が整いました。
次のfor文で、1日〜月末($end_day)までループし、日にちを出力していきます。
for( $j=1; $j <= $end_day; $j++ ) {
// ここに日にちを出力する処理が入る
}
1日のみ、開始の曜日を計算する必要があるため一手間かかります。
次の処理で、1日の曜日まで空のtd要素を挿入していきます。
if( $j === 1 ) {
echo '<tr>';
$weekday = date("w", $start_day_timestamp);
for( $k=0; $k<$weekday; $k++ ) {
echo '<td></td>';
}
}
具体的には、$start_day_timestampに入っている月初のタイムスタンプを使ってdate関数から曜日を取得します。
そして、その曜日になるまでfor文で空のtd要素を並べています。
例えば1日が水曜日だった場合は、日曜〜火曜まで空のtd要素を挿入します。
反対に、1日が日曜だった場合は空要素が挿入されません。
続くコードでは、td要素でマークアップした日にちを出力します。
その後、$weekdayに入っている曜日も1つ進めます。
echo '<td>'.$j.'</td>';
$weekday++;
もし$weekdayの数値が7以上になった場合は、曜日が土曜まで進んだことになるため日曜の「0」をセットします。
その時点でテーブルの行も改行となるため、締めのtr要素と次の開始であるtr要素を出力します。
if( 6 < $weekday ) {
echo '</tr><tr>';
$weekday = 0;
}
以上が、カレンダーの出力部分になります。
最後に、出力したHTMLの表示を整えるためにCSSを記述します。
CSSの記述
CSSはstyle要素に記述します。
コード例
main {
display: flex;
flex-wrap: wrap;
}
table {
margin-right: 10px;
margin-bottom: 20px;
border: 1px solid #555;
}
table caption {
padding: 7px 0;
font-size: 86%;
color: #fff;
line-height: 1.0em;
background: #555;
}
table th,
table td {
padding: 0 5px;
font-size: 86%;
color: #222;
text-align: center;
}
table td {
text-align: right;
}
以上がカレンダーを表示するコードになります。
このコードを実行すると、冒頭の画像のようなカレンダーが表示されます。
「年」を「2020」に設定すると、その年のカレンダーがしっかり表示されます。