일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 대분류/중분류/소분류
- 이메일로 인증코드 전송 구현
- jsp 프로젝트
- Oracle
- Level 1
- Spring
- Sts
- ajax
- 세션
- jsp
- jakarta.mail
- 다중 카테고리 구현
- 일단_해보는거야
- MVC
- 자바
- 스프링
- 교보문고 따라하기
- 로그인과 장바구니 구현
- MySQL
- 고객센터 구현
- 인증코드로 비밀번호 변경 구현
- 오라클
- 코딩
- js
- json
- 프로그래머스
- java
- SESSION
- jquery
- Spring MVC
감 잃지말고 개발하기
[JS] Date 객체를 이용한 특정 날짜의 주 구하기 본문
코드 목표
♠ Date 객체를 이용해 특정 날짜의 주를 구할 수 있다.
1주의 첫날 및 첫 번째 주(週)에 대한 정의
코드를 작성하기 앞서, 특정 달의 주를 계산하기 위해 필요한 정의를 살펴보자.
월요일 : 1주의 첫날
국제표준화기구인 ISO에서 제정한 국제표준 ISO 8601 (날짜 및 시각의 표기)에 따르면, 월요일을 한 주의 첫 번째 날로 규정하고 있다.
때문에 우리나라 국가표준(KS) 중 하나인 '데이터 요소 및 교환 포맷-정보교환-날짜 및 시각의 표기(분류번호 : KS X ISO 8601)'에서 역시 ISO의 규정에 따라 월요일을 1주의 첫날로 규정하고 있다.
주 구분 기준
[KS X ISO 8601]에 따르면, 일 년의 첫 주는 일 년의 첫 번째 목요일을 포함하는 주로 정의하고 있다.
접근 방법
구해야 하는 것은 '주어진 날짜가 해당 월의 몇 번째 주에 위치하는가' 것이다.
여기서 말한 주란, 위의 주 구분 기분에서 설명한 것처럼 목요일을 포함하는 주를 말한다.
이에 따라
1일이 속한 주가 첫 번째 주가 되기 위해선 1일이 월 ~ 목요일 중에 있어야 하며,
마지막 날이 속한 주가 마지막 주가 되기 위해선 마지막 날이 목 ~ 일요일 중에 있어야 한다.
2023년 6월의 경우,
1일은 목요일, 30일은 금요일이므로 각각의 주는 6월의 첫 주와 마지막 주가 된다.
하지만 2023년 7월의 경우,
1일은 토요일, 31일은 월요일이므로 각각의 주는 6월의 마지막 주와 8월의 첫 주가 된다.
그렇다면, 1일이 속한 주와 월의 마지막 날이 속한 주의 모습을 몇 가지 경우로 나누어 특정 날짜의 주를 구해보자.
구하고자 하는 날짜는 23일이다.
경우 1. 1일이 속한 주가 첫 주인 경우
즉, 1일이 월 ~ 목요일 사이에 있는 경우이다.
이 같은 경우, 1일이 월요일인지 아닌지에 따라 다시 구분할 수 있다.
월요일을 기준으로 한 이유는 월요일이 한 주의 시작이기 때문이다.
(1) 1일이 월요일인 경우
1일이 속한 주가 첫 주가 되면서 월요일인 경우이다.
보통 이 경우, 2023년 5월처럼 마지막 날이 속한 주는 다음 달의 첫 주가 된다.
하지만 2021년 2월처럼 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우도 있다.
[1] 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우 (Ex. 2023년 5월)
- 첫 번째 월요일인 1일이 속한 주가 첫 번째 주가 된다.
- 1일을 기준으로 23일은 3주 후에 있다.
- 5월 23일은 5월 4번째 주에 있다.
[2] 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우 (Ex. 2021년 2월)
- 첫 번째 월요일인 1일이 속한 주가 첫 번째 주가 된다.
- 1일을 기준으로 23일은 3주 후에 있다.
- 2월 23일은 2월 4번째 주에 있다.
(2) 1일이 월요일이 아닌 경우
1일이 속한 주가 첫 주가 되지만 1일이 월요일이 아닌 경우이다.
보통 이 경우, 2023년 6월처럼 마지막 날이 속한 주는 해당 월의 마지막 주가 된다.
하지만 2023년 2월처럼 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우도 있다.
[1] 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우 (Ex. 2023년 2월)
- 첫 번째 월요일인 6일이 속한 주가 두 번째 주가 된다.
- 6일을 기준으로 23일은 2주 후에 있다.
- 2월 23일은 2월 4번째 주에 있다.
[2] 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우 (Ex. 2023년 6월)
- 첫 번째 월요일인 5일이 속한 주가 두 번째 주가 된다.
- 5일을 기준으로 23일은 2주 후에 있다.
- 6월 23일은 6월 4번째 주에 있다.
경우 2. 1일이 속한 주가 첫 주가 아닌 경우
즉, 1일이 금 ~ 일요일 사이에 있는 경우이다.
보통 이 경우, 2023년 7월처럼 마지막 날이 속한 주는 다음 달의 첫 주가 된다.
하지만 2022년 4월처럼 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우도 있다.
[1] 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우 (Ex. 2023년 7월)
- 첫 번째 월요일인 3일이 속한 주가 첫 번째 주가 된다.
- 3일을 기준으로 23일은 2주 후에 있다.
- 7월 23일은 7월 3번째 주에 있다.
[2] 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우 (Ex. 2022년 4월)
- 첫 번째 월요일인 4일이 속한 주가 첫 번째 주가 된다.
- 4일을 기준으로 23일은 2주 후에 있다.
- 4월 23일은 4월 3번째 주에 있다.
코드 작성
위 경우의 수를 코드로 작성해 보자.
1. 변수 설정
먼저, 필요한 변수명과 저장할 값을 정의한다.
☞ 구하고자 하는 특정 날짜와 관련해 저장할 값
- year : 특정 날짜의 해당 연도
- month : 특정 날짜의 해당 월
- today : 특정 날짜
☞ 1일이 속한 주와 관련해 저장할 값
- firstDate : 해당 월의 1일
- firstDay : 1일의 요일
- firstMondayOfMonth : 해당 월의 첫 월요일 날짜
☞ 마지막 날짜가 속한 주와 관련해 저장할 값
- lastDate : 해당 월의 마지막 날짜
- lastDay : 마지막 날짜의 요일
- lastMondayOfMonth: 해당 월의 마지막 월요일 날짜
☞ 주와 관련해 저장할 값
- weekOfToday : 특정 날짜가 속한 주
2. 1일이 속한 주 및 마지막 날이 속한 주에서 필요한 값 추출
☞ Date 객체
- Date 객체에서의 월(Month) : JS에서 Date 객체의 월은 0부터 11까지의 값을 가지는데, 0은 1월을, 11은 12월을 나타낸다.
- Date 객체에서의 요일(Day) : JS에서 Date 객체의 요일은 일요일부터 시작하여 0부터 6까지의 값을 가지는데, 0은 일요일, 1은 월요일, 6은 토요일을 나타낸다.
- new Date(year, month, 0) : year년 (month+1)월의 0번째 날, 즉 month달의 마지막 날을 나타내는 Date 객체를 생성한다.
const date = new Date('2023-07-23');
const year = date.getFullYear();
const month = date.getMonth()+1;
const today = date.getDate();
// 1일이 속한 주
const firstDate = new Date(year, month-1, 1);
const firstDay = firstDate.getDay() === 0 ? 7 : firstDate.getDay();
const firstMondayOfMonth = firstDay === 1 ? 1 : firstDate.getDate() + (7-firstDay+1);
// 마지막 날짜가 속한 주
const lastDate = new Date(year, month, 0).getDate();
const lastDay =
new Date(year, month-1, lastDate).getDay() === 0 ? 7 : new Date(year, month-1, lastDate).getDay();
const lastMondayOfMonth = lastDate-lastDay+1;
console.log(`오늘은 ${month}월 ${today}일 입니다.`);
console.log(`${month}월의 첫 번째 날짜는 ${firstDate.getDay()}일이며, 요일은 ${firstDay}입니다.`);
console.log(`${month}월의 첫 월요일은 ${firstMondayOfMonth}일 입니다.`);
console.log(`${month}월의 마지막 날짜는 ${lastDate}일이며, 요일은 ${lastDay}입니다.`);
console.log(`${month}월의 마지막 월요일은 ${lastMondayOfMonth}일 입니다.`);
☞ const month = date.getMonth()+1;
- getMonth() : Date 객체에서 실제 월에 대응하는 월 값(0 ~ 11)을 가져온다.
- 위 코드에서 date.getMonth()은 7월에 해당하는 월 값인 6을 반환하기 때문에 1을 더해준다.
- 변수 month에는 7이 할당된다.
☞ const firstMondayOfMonth = firstDay === 1 ? 1 : firstDate.getDate() + (7-firstDay+1);
- 해당 월의 첫 월요일 날짜가 저장된다.
- firstDay가 1(월요일)인 경우엔 1(일)이, 1(월요일)이 아닌 경우엔 첫 번째 월요일 날짜가 저장되도록 한다.
☞ const lastDate = new Date(year, month, 0).getDate();
- 위 코드는 특정 연도와 월에 대한 마지막 날짜를 가져온다.
- month 변수에 7이 저장되어 있으므로 월 값인 7에 대응하는 8월의 0번째 날, 즉 7월의 마지막 날짜가 저장된다.
☞ const lastDay =
new Date(year, month-1, lastDate).getDay() === 0 ? 7 : new Date(year, month-1, lastDate).getDay();
- 날짜의 요일을 계산할 때 계산의 편리를 위해 일요일인 경우 7이 변수에 할당되도록 한다.
☞ const lastMondayOfMonth = lastDate - lastDay + 1;
- 해당 월의 마지막 월요일 날짜가 저장된다.
콘솔 확인
3. 경우의 수에 따른 특정 날짜의 주 계산
let weekOfToday = Math.floor((today-firstMondayOfMonth) / 7);
if (firstDay <= 4) {
// 1일이 월~목요일에 존재 : 1일 있는 주가 첫 주인 경우
if(firstMondayOfMonth == 1) {
// 1일이 속한 주가 첫 주면서 첫 번째 월요일인 경우
console.log("경우 1-(1)");
weekOfToday += 1;
} else {
// 1일이 속한 주가 첫 주이지만 1일이 첫 번째 월요일이 아닌 경우
// 첫 번째 월요일이 속한 주가 두 번째 주가 된다.
console.log("경우 1-(2)");
weekOfToday += 2;
}
} else {
// 1일이 금~일요일에 존재 : 1일 있는 주가 해당 월의 주가 되지 못하는 경우
// 첫 월요일이 있는 주가 첫 주가 된다.
console.log("경우 2");
weekOfToday += 1;
}
if(lastDay < 4) {
// 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우
console.log("경우 [1]");
if(lastMondayOfMonth <= today) {
// 구하고자 하는 특정 날짜가 해당 월의 마지막 월요일 날짜 이후에 있는 경우
weekOfToday = 7;
}
} else console.log("경우 [2]");
console.log(`weekOfToday : ${weekOfToday}`);
☞ let weekOfToday = Math.floor((today-firstMondayOfMonth) / 7);
- 구하고자 하는 특정 날짜가 첫 월요일을 기준으로 몇 주 후에 있는지를 구한다.
- Math 객체의 floor() 함수 : 소수점 이하를 버리고 가장 가까운 작은 정수로 내림한다.
- 만약 1일이 속한 주가 첫 주가 아닌 경우(경우 2), 변수 weekOfToday에는 -1이 할당된다.
☞ if (firstDay <= 4) { }
- 1일이 속한 주가 해당 월의 첫 번째 주인 경우(경우 1)이다.
- 여기서 다시 두 가지 경우로 나뉜다.
- 1일이 월요일인 경우(경우 (1)), 1일이 첫 번째 월요일이 되므로 weekOfToday에 1을 더한다.
- 만약 1일이 월요일이 아닌 경우(경우(2)), firstMondayOfMonth의 날짜가 첫 번째 월요일이자 두 번째 주의 시작이 되므로 weekOfToday에 2를 더한다.
☞ else { }
- 1일이 속한 주가 해당 월의 주가 되지 못하는 경우(경우 2)이므로 weekOfToday에 1을 더한다.
☞ if(lastDay < 4) { }
- 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우(경우 [1])이다.
콘솔 확인
4. weekOfToday 처리
switch(weekOfToday) {
case 0:
console.log(`${month}월의 ${today}일은 ${month-1}월 마지막 주에 있습니다.`);
break;
case 7:
console.log(`${month}월의 ${today}일은 ${month+1}월 첫 주에 있습니다.`);
break;
default:
console.log(`${month}월의 ${today}일은 ${weekOfToday}번째 주에 있습니다.`);
}
콘솔 확인
코드 확인
이렇게 주어진 날짜가 속한 주를 구하기 위한 코드가 완성되었다.
위에서 코드를 작성하면서 경우 2에 대한 확인을 해봤으니 다른 경우 역시 확인해 보자.
경우 1. 1일이 속한 주가 첫 주인 경우
(1) 1일이 월요일인 경우
[1] 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우 (Ex. 2023년 5월 30일)
[2] 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우 (Ex. 2021년 2월 27일)
(2) 1일이 월요일이 아닌 경우
[1] 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우 (Ex. 2023년 2월 26일)
[2] 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우 (Ex. 2023년 6월 16일)
경우 2. 1일이 속한 주가 첫 주가 아닌 경우
[2] 마지막 날이 속한 주가 해당 월의 마지막 주가 되는 경우 (Ex. 2022년 4월 2일)
전체 코드
function getWeekOfMonth(date) {
const year = date.getFullYear();
const month = date.getMonth()+1;
const today = date.getDate();
// 1. 해당 월의 1일과 마지막 일의 요일 및 날짜 계산
const firstDate = new Date(year, month-1, 1);
const firstDay = firstDate.getDay() === 0 ? 7 : firstDate.getDay();
const firstMondayOfMonth = firstDay === 1 ? 1 : firstDate.getDate() + (7-firstDay+1); // 첫 월요일 날짜
const lastDate = new Date(year, month, 0).getDate();
const lastDay = new Date(year, month-1, lastDate).getDay() === 0 ? 7 : new Date(year, month-1, lastDate).getDay();
const lastMondayOfMonth = lastDate-lastDay+1;
// 2. 경우의 수에 따른 특정 날짜의 주 계산
let weekOfToday = Math.floor((today-firstMondayOfMonth) / 7); // 1일이 속한 주가 첫 주가 아닌 경우 -1이 할당됨
if (firstDay <= 4) {
// 1일이 월~목요일에 존재 : 1일 있는 주가 첫 주인 경우
if(firstMondayOfMonth == 1) {
// 1일이 속한 주가 첫 주면서 첫 번째 월요일인 경우
console.log("경우 1-(1)");
weekOfToday += 1;
} else {
// 1일이 속한 주가 첫 주이지만 1일이 첫 번째 월요일이 아닌 경우 : 첫 번째 월요일이 속한 주가 두 번째 주가 된다.
console.log("경우 1-(2)");
weekOfToday += 2;
}
} else {
// 1일이 금~일요일에 존재 : 1일 있는 주가 해당 월의 주가 되지 못하는 경우 : 첫 월요일이 있는 주가 첫 주가 된다.
console.log("경우 2");
weekOfToday += 1;
}
if(lastDay < 4) {
// 마지막 날이 속한 주가 다음 달의 첫 주가 되는 경우
console.log("경우 [1]");
if(lastMondayOfMonth <= today) {
weekOfToday = 7;
}
} else console.log("경우 [2]");
console.log(`weekOfToday : ${weekOfToday}`);
// 3. weekOfToday 처리
switch(weekOfToday) {
case 0:
console.log(`${month}월의 ${today}일은 ${month-1}월 마지막 주에 있습니다.`);
break;
case 7:
console.log(`${month}월의 ${today}일은 ${month+1}월 첫 주에 있습니다.`);
break;
default:
console.log(`${month}월의 ${today}일은 ${weekOfToday}번째 주에 있습니다.`);
}
}
getWeekOfMonth(new Date('2022-04-02'));
Date 객체를 이용한 특정 날짜의 주 구하기 끝.
'프론트엔드 > JS' 카테고리의 다른 글
[JS][JQuery] 배열 데이터를 select 요소에 넣기 (0) | 2023.06.15 |
---|---|
[JS][JQuery] 속성 data-value 가져오는 방법 (0) | 2023.05.27 |