벌써 다섯번째 글을 작성하네요. 이번에는 자바스크립트 달력을 만들어볼까 합니다. 스마트폰이나 윈도우 화면에서 쉽게 확인할 수 있는 달력을 한번 구현해보면서 공부해볼까 합니다. 사실 이미 만들어져 있는 달력 라이브러리들이 많지만, 그래도 직접 구현해보면 공부도 되고, 좋을 것 같아서 시작하게 되었습니다.

1. 설계
① 월(Month) 구현하기
달력을 만들면서 가장 먼저 당황했던 건 new Date().getMonth() 결과값이었습니다. 분명 지금은 1월인데 컴퓨터는 자꾸 0이라고 답하더라고요. 처음엔 제가 코드를 잘못 짠 줄 알고 한참을 들여다봤습니다. 알고 보니 자바스크립트에서 월은 0(1월)부터 11(12월)까지 인덱스로 관리된다는 사실을 알았습니다. 그래서 Date().getMonth() 값에 1을 더해주는게 중요했습니다.
② 이번 달의 마지막 날, 어떻게 찾을까?
달력을 그리려면 이번 달이 30일까지인지, 31일까지인지, 혹은 2월처럼 28일(윤년엔 29일)인지 알아내는 게 핵심이었습니다.
처음엔 if문으로 달마다 숫자를 다 지정해야 하나 고민했는데, 정말 마법 같은 방법을 찾았습니다. new Date(year, month + 1, 0)처럼 다음 달의 0번째 날을 요청하면, 컴퓨터가 알아서 이번 달의 마지막 날짜를 알려주더라고요! 이 한 줄의 코드로 복잡한 조건문이 사라졌을 때, 코딩의 효율성에 다시 한번 감탄했습니다.
③ 빈 칸을 채우는 미학
1일이 항상 일요일에서 시작하지 않잖아요? 첫 주에 지난달의 날짜들이 머물렀던 빈 칸을 계산해서 띄워주는 로직이 가장 까다로웠습니다.
getDay() 함수로 1일의 요일을 알아내고, 그만큼 빈 박스를 생성해주는 과정을 거치면서 레이아웃이 딱딱 들어맞을 때의 그 쾌감! CSS Grid로 repeat(7, 1fr)를 설정해 요일별로 버튼들을 정렬하고 나니, 비로소 제가 알던 그 ‘달력’의 모습이 갖춰졌습니다.
2. HTML 코드
상단에는 연도와 월을 표시해주고, 양 옆에는 달을 넘길 수 있는 버튼을 두었습니다.
하단에는 요일과 그 연도와 월에 맞는 일이 보이도록 나열하였습니다.
<div class="calendar">
<div class="header">
<button class="nav-btn" onclick="moveMonth(-1)"><</button>
<h2 id="monthDisplay">2026.01</h2>
<button class="nav-btn" onclick="moveMonth(1)">></button>
</div>
<div class="days">
<div>일</div>
<div>월</div>
<div>화</div>
<div>수</div>
<div>목</div>
<div>금</div>
<div>토</div>
</div>
<div id="datesGrid" class="dates"></div>
</div>
3. CSS Grid로 완성한 디자인
달력의 레이아웃은 지난번 계산기 프로젝트에서 공부했던 CSS Grid를 다시 활용했습니다. 요일별로 7개의 열을 맞추는 게 예전 같으면 정말 어려웠을 텐데, 이제는 grid-template-columns: repeat(7, 1fr); 한 줄이면 충분하다는 걸 압니다. 1일이 시작되기 전 빈 칸들을 getDay() 함수로 계산해서 채워 넣고, 날짜들이 격자 모양으로 딱딱 들어맞는 화면을 보니 비로소 제가 알던 ‘진짜 달력’ 같아 보여서 정말 뿌듯하더라고요.
4. 자바스크립트 달력 코드
① 달의 마지막 날을 찾는 로직
앞서 언급한대로 달의 마지막 날을 찾는 로직이 중요하다고 생각했습니다.
달력을 그리려면 이번 달이 30일까지인지, 31일까지인지 정확히 알아내는 게 핵심입니다. 처음엔 if문으로 달마다 숫자를 다 지정해야 하나 고민하며 머리를 싸맸는데, 공부하다 보니 정말 마법 같은 방법을 찾았습니다.
// 이번 달의 마지막 날짜를 구하는 핵심 로직
const viewYear = date.getFullYear();
const viewMonth = date.getMonth();
// 다음 달의 0번째 날을 요청하면, 이번 달의 마지막 날이 나옵니다!
const thisLast = new Date(viewYear, viewMonth + 1, 0);
const lastDate = thisLast.getDate();
new Date(year, month + 1, 0)처럼 다음 달의 0번째 날을 요청하면, 컴퓨터가 알아서 이번 달의 마지막 날짜를 알려주더라고요! 이 한 줄의 코드로 복잡한 조건문 수십 줄이 사라졌을 때의 그 쾌감은 정말 잊을 수 없습니다. 코딩의 효율성과 라이브러리의 소중함을 다시 한번 느낀 순간이었죠.
5. 자바스크립트 달력 실행 영상

6. 보완하거나 추가할 사항
지금은 단순히 달력 기능만을 구현했지만, 아래와 같은 기능들을 추가하면 조금 더 완성도 높은 달력이 될 것 같습니다.
- 일정 메모 기능: 특정 날짜를 클릭하면 메모를 남길 수 있는 기능을 추가하여 일정을 적을 수 있도록 하면 좋을 것 같습니다.
- 일정 저장 기능: LocalStorage를 활용하여 추가된 메모나 일정을 브라우저를 껐다 다시 켜도 유지될 수 있도록 구현하면 실생활에서도 사용가능한 달력이 만들어질 것 같습니다.
- 토일 색상 교체: 토요일은 파란색, 일요일은 빨간색으로 변경해주면 더 직관적인 달력이 될 것 같습니다.
- 공휴일 API 연동: 지금은 모든 날짜가 검은색인데, 공공데이터 API를 가져와서 빨간 날(공휴일)을 자동으로 표시해주는 기능을 추가하면 완벽한 자바스크립트 달력이 될 것 같습니다.
7. 참고
단순히 숫자를 나열하는 것 같지만, 그 속에서 요일과 날짜의 규칙을 찾아가는 과정이 정말 즐거웠던 프로젝트였습니다. 1일부터 말일까지 화면에 가득 채워진 숫자를 보니, 제가 자바스크립트와 한 걸음 더 친해진 것 같아 기분이 좋습니다.
기존에 만들었던 To do List와 오늘 만든 달력, 그리고 앞서 언급했던 보완점들을 더해서 하나의 다이어리 웹앱을 만들어도 좋을 것 같습니다. 다음번에 기회가 된다면 나만의 다이어리를 자바스크립트로 만들어보도록 하겠습니다.