Javascript 입력한 날짜의 해당 달 기준, 주차 구하기

Explanation

제목 그대로, 자바스크립트로 입력받은 날짜가 해당 달의 몇 주차인지 구하는 함수 입니다.

2018.08.27 수정사항

코드에 오류가 있어서 수정하였습니다.
의식에 흐름대로 짜서 그런지.. 코드가 길고 복잡하네요..
잘못된 점이나 더 좋은 방법을 아시면 댓글로 알려주세요 :)

코드

function weekNumberByMonth(dateFormat) {
  const inputDate = new Date(dateFormat);

  // 인풋의 년, 월
  let year = inputDate.getFullYear();
  let month = inputDate.getMonth() + 1;

  // 목요일 기준 주차 구하기
  const weekNumberByThurFnc = (paramDate) => {

    const year = paramDate.getFullYear();
    const month = paramDate.getMonth();
    const date = paramDate.getDate();

    // 인풋한 달의 첫 날과 마지막 날의 요일
    const firstDate = new Date(year, month, 1);
    const lastDate = new Date(year, month+1, 0);
    const firstDayOfWeek = firstDate.getDay() === 0 ? 7 : firstDate.getDay();
    const lastDayOfweek = lastDate.getDay();

    // 인풋한 달의 마지막 일
    const lastDay = lastDate.getDate();

    // 첫 날의 요일이 금, 토, 일요일 이라면 true
    const firstWeekCheck = firstDayOfWeek === 5 || firstDayOfWeek === 6 || firstDayOfWeek === 7;
    // 마지막 날의 요일이 월, 화, 수라면 true
    const lastWeekCheck = lastDayOfweek === 1 || lastDayOfweek === 2 || lastDayOfweek === 3;

    // 해당 달이 총 몇주까지 있는지
    const lastWeekNo = Math.ceil((firstDayOfWeek - 1 + lastDay) / 7);

    // 날짜 기준으로 몇주차 인지
    let weekNo = Math.ceil((firstDayOfWeek - 1 + date) / 7);

    // 인풋한 날짜가 첫 주에 있고 첫 날이 월, 화, 수로 시작한다면 'prev'(전달 마지막 주)
    if(weekNo === 1 && firstWeekCheck) weekNo = 'prev';
    // 인풋한 날짜가 마지막 주에 있고 마지막 날이 월, 화, 수로 끝난다면 'next'(다음달 첫 주)
    else if(weekNo === lastWeekNo && lastWeekCheck) weekNo = 'next';
    // 인풋한 날짜의 첫 주는 아니지만 첫날이 월, 화 수로 시작하면 -1;
    else if(firstWeekCheck) weekNo = weekNo -1;

    return weekNo;
  };

  // 목요일 기준의 주차
  let weekNo = weekNumberByThurFnc(inputDate);

  // 이전달의 마지막 주차일 떄
  if(weekNo === 'prev') {
    // 이전 달의 마지막날
    const afterDate = new Date(year, month-1, 0);
    year = month === 1 ? year - 1 : year;
    month = month === 1 ? 12 : month - 1;
    weekNo = weekNumberByThurFnc(afterDate);
  }
  // 다음달의 첫 주차일 때
  if(weekNo === 'next') {
    year = month === 12 ? year + 1 : year;
    month = month === 12 ? 1 : month + 1;
    weekNo = 1;
  }

  return {year, month, weekNo};
}

예시

weekNumberByMonth('2018-09-05'); 
// {year: 2018, month: 9, weekNo: 1}
// 2018년 9월 5일은 2018년 9월의 1주차
weekNumberByMonth(new Date(2018,8,5)); 
// {year: 2018, month: 9, weekNo: 1}
// 2018년 9월 5일은 2018년 9월의 1주차
weekNumberByMonth('2014-03-01'); 
// {year: 2014, month: 2, weekNo: 4}
// 2014년 3월 1일은 2014년 2월의 4주차
weekNumberByMonth('2016-01-02'); 
// {year: 2015, month: 12, weekNo: 5}
// 2016년 1월 2일은 2015년 12월의 5주차
weekNumberByMonth(new Date(2018,6,30));
// {year: 2018, month: 8, weekNo: 1}
// 2018년 7월 30일은 2018년 8월 1주차

끝