react 와 moment.js 그리고 styled-component를 이용하여 캘린더를 만들어 보았다.
Date()와 비슷하지만 더 편리하게 사용 할 수 있는 날짜,시간 라이브러리이다.moment()라는 함수를 사용하며 리턴 값으로 날짜와 method들이 담겨있는 객체를 반환한다.npm install moment --save
yarn add moment
moment()console.log(moment())

console.log(moment("2019-05-11"))

.clone()moment()객체에 다른 method를 쓸 경우 원본 값이 바뀌기 때문에 .clone() mehtod로 복제해서 원본을 유지하는 역활을 한다.
moment().clone()
.format()인자로 날짜의 형식을 받아서 moment()객체를 문자열로 출력해준다.
console.log(moment().format("YYYY-MM"));
// 2022-08
console.log(moment().format("YYYY-MM-DD"));
// 2022-08-12
console.log(moment().format("MM-DD"));
// 08-12
console.log(moment().format("DD-MM"));
// 12-08
.startOf() .endOf()moment()객체를 기준으로 인자로 받은 단위 기간의 처음과 끝을 알려준다.
ex) 오늘 기준 이번달의 첫날
console.log(moment().clone().startOf("month").format("YYYY-MM-DD"));
// 2022-08-01
ex) (오늘 기준 이번달의 첫날)을 기준으로 이번주의 첫날
console.log(moment().clone().startOf("month").startOf("week").format("YYYY-MM-DD"));
// 2022-07-31
.isBefore() .issame() .isAfter()moment()객체를 기준으로 첫번째 인자와의 대소를 비교한다. 두번째 인자로는 비교할 단위를 받는다.
// endDay가 지금보다 이전인지 date단위로 비교
moment().isBefore(endDay, "day")
// endDay가 지금이랑 같은 달인지 month단위로 비교
moment().isSame(endDay, "month")
.add() .subtract()moment()객체를 기준으로 첫번째 인자로 받은 값 만큼 두번째 인자 단위로 빼거나 더한다.
//오늘 보다 일주일 후
moment().add(1, "week")
//오늘 보다 3일 전
moment().subtract(3, "day")
앞서 배운 moment.js를 활용하면 오늘을 기준으로 이번달의 첫날과 마지막 날을 구할 수 있다.
moment().clone().startOf("month")
// 2022-08-01
moment().clone().endOf("month")
// 2022-08-31
하지만 달력에서는 이번달 뿐만이 아니라 첫날과 끝날이 속한 week의 날짜들을 전부 표시해줘야된다.
그렇다면 위에 코드에 .startOf("week")와 .endOf("week")를 추가해 보자
const startDay = moment().clone().startOf("month").startOf("week")
// 2022-07-31
const endDay = moment().clone().endOf("month").endOf("week")
// 2022-09-03
자 이제 이번달에 보여 줄 날짜들을 달력으로 만들기 좋게 2차원 리스트로 만들어보자
[week , week, week, week, ...]의 형식으로
const day = startDay.clone().subtract(1, "day");
while (day.isBefore(endDay, "day")) {
calendar.push(
Array(7)
.fill(0)
.map(() => day.add(1, "day").clone())
);
}
startDay 보다 하루 전을 day라고 지정한 후day 가 endDay 가 될때 까지 while 문을 돌려보자week 배열을 0으로 채운 뒤 각각의 위치에 day의 값을 1일 씩 더해서 채워 준다.
위의 코드를 build.js라는 로직으로 분리해 놓겠다.
//build.js
const buildCalendar = (value) => {
const startDay = value.clone().startOf("month").startOf("week");
const endDay = value.clone().endOf("month").endOf("week");
const day = startDay.clone().subtract(1, "day");
const calendar = [];
while (day.isBefore(endDay, "day")) {
calendar.push(
Array(7)
.fill(0)
.map(() => day.add(1, "day").clone())
);
}
return calendar;
};
export default buildCalendar;