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;