カレンダー

簡単なカレンダーを実装する方法をご紹介します。
なお、祝日の表記等はありませんのでご注意ください。

デモ

関数定義

JavaScript (ES5)

/**
 * カレンダーを生成
 * @param {number} [year] カレンダーとして表示する年(指定しなかった場合は現在の年が設定される)
 * @param {number} [month] カレンダーとして表示する月(指定しなかった場合は現在の月が設定される)
 * @param {number} [day] 日付部分にマークする日(指定しなかった場合は現在の月が設定される)
 * @return {Element} 生成されたカレンダーのtable要素を返す。
 */
var createCalendar = function(year, month, day) {
	var tableElem = document.createElement('table'),
	    theadElem = tableElem.createTHead(),
	    tbodyElem = tableElem.createTBody();

	var dateObj = new Date();

	if (typeof year  === 'undefined') year  = dateObj.getFullYear();
	if (typeof month === 'undefined') month = dateObj.getMonth() + 1;
	if (typeof day   === 'undefined') day   = dateObj.getDate();

	var week       = ['日', '月', '火', '水', '木', '金', '土'], // 日本語の曜日を定義
	    whitespace = '-', // 空白に埋める文字
	    lastDay    = (new Date(year, month, 0)).getDate(), // 月末の日を取得
	    toDate     = dateObj.getFullYear() + ('0' + (dateObj.getMonth() + 1)).slice(-2) + ('0' + dateObj.getDate()).slice(-2), // 現在の日付をyyyymmddで設定
	    trElem, cellElem, n, i, len;

	// 年月のキャプションを追加
	var capElem = tableElem.createCaption();
	capElem.appendChild(document.createTextNode(year + '年' + month + '月'));

	// 曜日のセルを追加
	trElem = theadElem.insertRow();
	week.forEach(function(val) {
		cellElem = document.createElement('th');
		cellElem.appendChild(document.createTextNode(val));
		trElem.appendChild(cellElem);
	});

	// 日付のセルを追加
	for (n = 1; n <= lastDay; n++) {
		dateObj = new Date(year, month - 1, n);

		// 行を追加
		if (n === 1 || dateObj.getDay() === 0) trElem = tbodyElem.insertRow();

		// 1日までのセルを埋める
		if (n === 1 && dateObj.getDay() > 0) {
			for (i = 0; i < 7 - (7 - dateObj.getDay()); i++) {
				cellElem = trElem.insertCell(-1);
				cellElem.appendChild(document.createTextNode(whitespace));
			}
		}

		cellElem = trElem.insertCell(-1);

		if (toDate === year + ('0' + month).slice(-2) + ('0' + n).slice(-2)) {
			cellElem.className = 'today';
		}

		cellElem.appendChild(document.createTextNode(n));
	}

	// 最後のセルを埋める(例えば月末が月曜日の場合は火曜日~土曜日までを埋める)
	if (dateObj.getDay() < 6) {
		for (i = 0; i < 6 - dateObj.getDay(); i++) {
			cellElem = trElem.insertCell(-1);
			cellElem.appendChild(document.createTextNode(whitespace));
		}
	}

	// 最後の空白行を追加(日付の行を6行に揃える)
	var rowCount = tableElem.rows.length;
	if (rowCount < 7) {
		for (n = rowCount; n < 7; n++) {
			trElem = tbodyElem.insertRow();
			for (i = 0; i < 7; i++) {
				cellElem = trElem.insertCell(-1);
				cellElem.appendChild(document.createTextNode(whitespace));
			}
		}
	}

	return tableElem;
};

JavaScript (ES6以降)

/**
 * カレンダーを生成
 * @param {number} [year] カレンダーとして表示する年(指定しなかった場合は現在の年が設定される)
 * @param {number} [month] カレンダーとして表示する月(指定しなかった場合は現在の月が設定される)
 * @param {number} [day] 日付部分にマークする日(指定しなかった場合は現在の月が設定される)
 * @returns {Element} 生成されたカレンダーのtable要素を返す。
 */
const createCalendar = (year, month, day) => {
	const tableElem = document.createElement('table'),
	      theadElem = tableElem.createTHead(),
	      tbodyElem = tableElem.createTBody();

	const dateObj = new Date();

	if (typeof year  === 'undefined') year  = dateObj.getFullYear();
	if (typeof month === 'undefined') month = dateObj.getMonth() + 1;
	if (typeof day   === 'undefined') day   = dateObj.getDate();

	const week       = ['日', '月', '火', '水', '木', '金', '土'], // 日本語の曜日を定義
	      whitespace = '-'; // 空白に埋める文字

	const lastDay = (new Date(year, month, 0)).getDate(), // 月末の日を取得
	      toDate  = dateObj.getFullYear() + ('0' + (dateObj.getMonth() + 1)).slice(-2) + ('0' + dateObj.getDate()).slice(-2); // 現在の日付をyyyymmddで設定

	let trElem, cellElem;

	// 年月のキャプションを追加
	const capElem = tableElem.createCaption();
	capElem.appendChild(document.createTextNode(`${year}年${month}月`));

	// 曜日のセルを追加
	trElem = theadElem.insertRow();
	week.forEach(val => {
		cellElem = document.createElement('th');
		cellElem.appendChild(document.createTextNode(val));
		trElem.appendChild(cellElem);
	});

	// 日付のセルを追加
	for (let n = 1; n <= lastDay; n++) {
		const day = (new Date(year, month - 1, n)).getDay();

		// 行を追加
		if (n === 1 || day === 0) trElem = tbodyElem.insertRow();

		// 1日までのセルを埋める
		if (n === 1 && day > 0) {
			for (let i = 0; i < 7 - (7 - day); i++) {
				cellElem = trElem.insertCell(-1);
				cellElem.appendChild(document.createTextNode(whitespace));
			}
		}

		cellElem = trElem.insertCell(-1);

		if (toDate === year + ('0' + month).slice(-2) + ('0' + n).slice(-2)) {
			cellElem.classList.add('today');
		}

		cellElem.appendChild(document.createTextNode(n));
	}

	// 最後のセルを埋める(例えば月末が月曜日の場合は火曜日~土曜日までを埋める)
	if (dateObj.getDay() < 6) {
		for (let i = 0; i < 6 - dateObj.getDay(); i++) {
			cellElem = trElem.insertCell(-1);
			cellElem.appendChild(document.createTextNode(whitespace));
		}
	}

	// 最後の空白行を追加(日付の行を6行に揃える)
	const rowCount = tableElem.rows.length;
	if (rowCount < 7) {
		for (let n = rowCount; n < 7; n++) {
			trElem = tbodyElem.insertRow();
			for (let i = 0; i < 7; i++) {
				cellElem = trElem.insertCell(-1);
				cellElem.appendChild(document.createTextNode(whitespace));
			}
		}
	}

	return tableElem;
};

使い方

引数を指定することにより、指定した年月のカレンダーを表示することができます。
現在の日付を示すクラス名todayをtd要素に付与しています。

関数はtable要素を返すので、返ってきたtable要素を出力したい要素に挿入することでカレンダーが表示されます。

構文

ES5

var element = createCalendar([year], [month], [day]);

ES6以降

const element = createCalendar([year], [month], [day]);

引数

引数名 説明
第一引数 year number カレンダーとして表示する年。
省略した場合は現在の年が設定される。
第二引数 month number カレンダーとして表示する月。
省略した場合は現在の月が設定される。
第三引数 day number 日付部分にマークする日。
省略した場合は現在の日が設定される。

戻り値

交点の座標(x軸、y軸)と交差しているかどうか、平行かどうかを返します。

サンプルコード

JavaScript (ES5)

// 現在の月のカレンダー
var calendarElem = createCalendar();

// 指定の年月のカレンダーを表示する場合
var calendarElem = createCalendar(2011, 5);

document.body.appendChild(calendarElem);

JavaScript (ES6以降)

// 現在の月のカレンダー
const calendarElem = createCalendar();

// 指定の年月のカレンダーを表示する場合
const calendarElem = createCalendar(2011, 5);

document.body.appendChild(calendarElem);

JavaScript逆引きリファレンス一覧へ戻る