【javascript】カレンダーの作り方 new date()で日付を取得、計算し、テーブルに表示

今月のカレンダー
今回は以下のような、一ヶ月のカレンダーをjavascriptで作ってみたいと思います。
参考
デザインがおしゃれになりました。

HTML
HTMLは2行だけです。#calendarにHTMLを生成させます。
<p class="yearMonth"></p>
<div id="calendar"></div>
年月表示とカレンダーの1行目
以下の部分を作ってみましょう。

CSS
.yearMonth{
margin: 10px;
font-weight: bold;
}
#calendar {
margin: 10px auto;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
.day{
background: rgb(233, 255, 255);
font-weight: bold;
}
td {
border: 1px solid #ddd;
padding: 10px;
text-align: center;
}
/* 土曜日 */
td:nth-child(6) {
color: royalblue;
}
/* 日曜日 */
td:last-child {
color: red;
}
javascript
3行目 : 月曜スタートの配列を準備
8行目 : 生成するHTMLを格納する変数
const calendar = document.getElementById("calendar");
const yearMonth = document.querySelector(".yearMonth");
const days = ["月", "火", "水", "木", "金", "土", "日"];
const date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
// HTMLを組み立てる変数
let calendarHtml = "";
// 年月の表示
yearMonth.textContent = `${year}年${month}月`;
calendarHtml += "<table><tr>";
// 曜日の行を作成(テーブル1行目)
for (let i = 0; i < days.length; i++) {
// 曜日を表示させる1行目にはクラスdayを付与する
calendarHtml += "<td class='day'>" + days[i] + "</td>";
}
calendarHtml += "</tr>";
先月末の表示
以下の部分を作ってみましょう。

javascript
4行目 : 先月の最終日を取得
6行目 : 今月の1日の曜日を取得(0~6)2022年9月は1日は木曜日なので取得される startDayは4。
14行目 : 月曜スタートで1日が木なので、先月末の月(29)、火(30)、水(31)を表示させる。
16行目 : 月曜スタートなので2を足す。日曜スタートなら1。
2022年9月の例)
31 - 4 + 0 + 2 = 29
31 - 4 + 1 + 2 = 30
31 - 4 + 2 + 2 = 31
18行目 : クラスis-disabledを付与
// 前月の最後の日の情報
const lastMonthEndDate = new Date(year, month - 1, 0);
// 前月の末日
const lastMonthEndDayCount = lastMonthEndDate.getDate();
// 月の最初の日の曜日を取得
const startDay = startDate.getDay();
// 6週分の行を生成
for (let w = 0; w < 6; w++) {
calendarHtml += "<tr>";
// 月~日まで
for (let d = 0; d < 7; d++) {
if (w == 0 && d < startDay - 1) { // 第一週目で、且つ今月1日の曜日の前まで
// 1行目で1日の前の日付
let num = lastMonthEndDayCount - startDay + d + 2;
calendarHtml +=
'<td class="is-disabled">' + num + "</td>";
}
}
来月最初の表示
以下の部分を作ってみましょう。

javascript
1, 8-14行目
10行目 : 来月の1日、2日・・・
2022年9月の例)
31 - 30 = 1
32 - 30 = 2
33 - 30 = 3
12行目 : クラスis-disabledを付与
let dayCount = 1; // 日にちのカウント
if (w == 0 && d < startDay - 1) {
// 1行目で1日の前の日付
let num = lastMonthEndDayCount - startDay + d + 2;
calendarHtml +=
'<td class="is-disabled">' + num + "</td>";
} else if (dayCount > endDayCount) {
// 末尾の日数を超えた
let num = dayCount - endDayCount;
calendarHtml +=
'<td class="is-disabled">' + num + "</td>";
dayCount++;
}
今月の表示
以下の部分を作ってみましょう。

javascript
7-17行目
9行目 : dayCountと今日の日付が一致したら、クラスtodayを付与
} else if (dayCount > endDayCount) {
// 末尾の日数を超えた
let num = dayCount - endDayCount;
calendarHtml +=
'<td class="is-disabled">' + num + "</td>";
dayCount++;
} else {
// 今日の日付にクラスtodayを付与
if(dayCount == today){
calendarHtml += `<td class="today">${dayCount}</td>`;
dayCount++;
}else{
calendarHtml += `<td>${dayCount}</td>`;
dayCount++;
}
}
CSS
今日の日付にCSSをあてる
.today{
background: rgb(212, 212, 212);
}
最後の行が不要の時
以下のように最後の行が不要の場合、要素を削除します。

// trをすべて取得
const tr = document.querySelectorAll(".calendar-container tr")
// 最終行の最初のtdにクラスis-disabledが含まれていれば、最終行を削除
if(tr[6].firstChild.classList.contains("is-disabled")){
tr[6].remove();
}
参考



まとめ
-
今月の最初の日を取得
new Date(year, month - 1, 1);
-
今月の最後の日を取得
new Date(year, month, 0);
-
前月の最後の日を取得
new Date(year, month - 1, 0);
- 以上の情報を基に、先月末、今月、来月初の日付を計算し、テーブルに表示する