JavaScript의 Date 객체를 사용하여 달력(Calendar)을 만들어 보겠습니다.
날짜를 기준으로 달력에 필요한 정보들을 계산하여 가져옵니다.
Date 객체의 getFullYear() 메서드, getMonth() 메서드, getDate() 메서드로 연도, 월, 일을 구합니다.
var date = new Date();
// 달력 연도
var calendarYear = date.getFullYear();
// 달력 월
var calendarMonth = date.getMonth() + 1;
// 달력 일
var calendarToday = date.getDate();
console.log(calendarYear);
--> 2022
console.log(calendarMonth);
--> 3
console.log(calendarToday);
--> 19
날짜를 기준으로 월의 마지막 일자를 구하는 방법은 2가지가 있습니다.
첫 번째는 월별 마지막 일자 배열과 윤년 계산으로 마지막 일자를 구하는 방법입니다.
const monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// 윤년 계산
if (calendarYear % 400 == 0) {
monthDays[1] = 29;
} else if (calendarYear % 100 == 0) {
monthDays[1] = 28;
} else if (calendarYear % 4 == 0) {
monthDays[1] = 29;
}
// 달력 월의 마지막 일
var calendarMonthLastDate = monthDays[date.getMonth()];
console.log(calendarMonthLastDate);
--> 31
두 번째는 생성자로 Date 객체를 생성하여 마지막 일자를 구하는 방법입니다.
Date 객체에서는 일자가 0이면 이전 달의 마지막 일자를 계산하여 이전 달의 마지막 날짜로 자동 설정됩니다.
var monthLastDate = new Date(2022, 3, 0); --> 월은 Zero Base으로 4월은 3입니다.
console.log(monthLastDate);
--> Thu Mar 31 2022 00:00:00 GMT+0900 (한국 표준시)
--> 2022-03-31 00:00:00
var monthLastDate = new Date(calendarYear, calendarMonth, 0);
// 달력 월의 마지막 일
var calendarMonthLastDate = monthLastDate.getDate(); --> 이전 달의 마지막 일
console.log(calendarMonthLastDate);
--> 31
날짜를 기준으로 월의 시작 요일을 구합니다.
var monthStartDay = new Date(calendarYear, date.getMonth(), 1);
// 달력 월의 시작 요일
var calendarMonthStartDay = monthStartDay.getDay();
--> 2
시작 요일은 달력을 만들 때 1일이 출력되는 위치가 됩니다.
이제 달력 만들 수 있는 모든 정보를 다 구했습니다.
정보를 이용하여 달력을 만들어 보겠습니다.
달력 만들기
for 문으로 달력을 만들기 위해서는 달력의 주 수를 미리 계산해야 합니다.
달력의 주 수는 월의 시작 요일인 위치와 월의 마지막 일자를 더하고 일주일인 7로 나누면 됩니다.
// 주 카운트
var calendarWeekCount = Math.ceil((calendarMonthStartDay + calendarMonthLastDate) / 7);
console.log(calendarWeekCount);
--> 5
2022년 3월의 주 수는 5주입니다.
table 태그로 주 수만큼 for 문을 실행하여 레이아웃(layout)을 만들겠습니다.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>달력 만들기</title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
</head>
<body>
<div id="calendar"></div>
<script>
var date = new Date();
// 달력 연도
var calendarYear = date.getFullYear();
// 달력 월
var calendarMonth = date.getMonth() + 1;
// 달력 일
var calendarToday = date.getDate();
var monthLastDate = new Date(calendarYear, calendarMonth, 0);
// 달력 월의 마지막 일
var calendarMonthLastDate = monthLastDate.getDate();
var monthStartDay = new Date(calendarYear, date.getMonth(), 1);
// 달력 월의 시작 요일
var calendarMonthStartDay = monthStartDay.getDay();
// 주 카운트
var calendarWeekCount = Math.ceil((calendarMonthStartDay + calendarMonthLastDate) / 7);
var html = "";
html += "<table style=\"border-collapse: collapse;\">";
for (var index1 = 0; index1 < calendarWeekCount; index1++) {
html += "<tr>";
for (var index2 = 0; index2 < 7; index2++) {
html += "<td style=\"border: solid 1px black; padding: 20px 20px;\"></td>";
}
html += "</tr>";
}
html += "</table>";
$("#calendar").html(html);
</script>
</body>
</html>
레이아웃(layout)을 화면으로 보기 위해 table 태그와 td 태그에 style로 border를 추가했습니다.
달력에 시작 요일부터 날짜가 출력되게 하기 위해서 td 태그 단위로 카운터 하고 카운터와 동일한 위치부터 날짜를 출력합니다.
var html = "";
html += "<table style=\"border-collapse: collapse;\">";
// 위치
var calendarPos = 0;
// 날짜
var calendarDay = 0;
for (var index1 = 0; index1 < calendarWeekCount; index1++) {
html += "<tr>";
for (var index2 = 0; index2 < 7; index2++) {
html += "<td style=\"border: solid 1px black; padding: 10px 10px; text-align: center;\">";
if (calendarMonthStartDay <= calendarPos) {
calendarDay++;
html += "<span style=\"display: block; padding: 10px 10px;\">" + calendarDay + "</span>";
}
html += "</td>";
calendarPos++;
}
html += "</tr>";
}
html += "</table>";
$("#calendar").html(html);
월 마지막 일자까지만 날짜가 출력에 조건을 추가합니다.
var html = "";
html += "<table style=\"border-collapse: collapse;\">";
// 위치
var calendarPos = 0;
// 날짜
var calendarDay = 0;
for (var index1 = 0; index1 < calendarWeekCount; index1++) {
html += "<tr>";
for (var index2 = 0; index2 < 7; index2++) {
html += "<td style=\"border: solid 1px black; padding: 10px 10px; text-align: center;\">";
if (calendarMonthStartDay <= calendarPos && calendarDay < calendarMonthLastDate) {
calendarDay++;
html += "<span style=\"display: block; padding: 10px 10px;\">" + calendarDay + "</span>";
}
html += "</td>";
calendarPos++;
}
html += "</tr>";
}
html += "</table>";
$("#calendar").html(html);
table 헤더에 요일을 추가하고 caption 태그로 월을 표시하겠습니다. 그리고 table 태그와 td 태그에 있는 style 중 border은 삭제하겠습니다.
var html = "";
html += "<table>";
html += "<caption style=\"font-size: larger; font-weight: bolder; color: red; text-align: left; padding: 10px 20px;\">" + calendarMonth + "월</caption>";
html += "<thead>";
html += "<tr>";
html += "<th>일</th><th>월</th><th>화</th><th>수</th><th>목</th><th>금</th><th>토</th>";
html += "</tr>";
html += "</thead>";
html += "<tbody>";
// 위치
var calendarPos = 0;
// 날짜
var calendarDay = 0;
for (var index1 = 0; index1 < calendarWeekCount; index1++) {
html += "<tr>";
for (var index2 = 0; index2 < 7; index2++) {
html += "<td style=\"padding: 10px 10px; text-align: center;\">";
if (calendarMonthStartDay <= calendarPos && calendarDay < calendarMonthLastDate) {
calendarDay++;
html += "<span style=\"display: block; padding: 10px 10px;\">" + calendarDay + "</span>";
}
html += "</td>";
calendarPos++;
}
html += "</tr>";
}
html += "</tbody>";
html += "</table>";
$("#calendar").html(html);
오늘 날짜를 붉은색 원으로 표시해 보겠습니다.
var html = "";
html += "<table>";
html += "<caption style=\"font-size: larger; font-weight: bolder; color: red; text-align: left; padding: 10px 20px;\">" + calendarMonth + "월</caption>";
html += "<thead>";
html += "<tr>";
html += "<th>일</th><th>월</th><th>화</th><th>수</th><th>목</th><th>금</th><th>토</th>";
html += "</tr>";
html += "</thead>";
html += "<tbody>";
// 위치
var calendarPos = 0;
// 날짜
var calendarDay = 0;
for (var index1 = 0; index1 < calendarWeekCount; index1++) {
html += "<tr>";
for (var index2 = 0; index2 < 7; index2++) {
html += "<td style=\"padding: 10px 10px; text-align: center;\">";
if (calendarMonthStartDay <= calendarPos && calendarDay < calendarMonthLastDate) {
calendarDay++;
html += "<span style=\"display: block; padding: 10px 10px;";
if (calendarDay == calendarToday) {
html += " border: 1px solid red; border-radius: 50%; color: white; background-color: red;";
}
html += "\">" + calendarDay + "</span>";
}
html += "</td>";
calendarPos++;
}
html += "</tr>";
}
html += "</tbody>";
html += "</table>";
$("#calendar").html(html);