방개
비밀번호를 잊어버리셨나요?

코드

특정 날짜가 몇 번째 주에 있는지 확인하는 법

    • 글자 크기

특정 날짜를 지정해준다면, 해당 날짜가 달력상에서 몇 번째 주에 있는지 확인하는 코드를 만들어보았습니다.

 

원래 지식IN에서 질문으로 들어온 내용인데, 내용이 흥미로워 방개에서도 한번 소개해드리고자 합니다.

우선, 들어가기에 앞서서 말씀드리면, 주 계산은 ISO 표준을 따르는 것이 아닌 정말로 "달력 상에서의 첫 줄을 첫 번째 주"라고 생각하였습니다. (지식IN 질문자님이 요청하신 사항입니다.) 즉, 1년이 52주가 아닌 훨씬 많아지겠죠.

 

때문에 오토핫키에 있는 내장 변수로는 사용을 못할 것이라 생각해서, 서기 달력 원리를 찾아보고나서 제작하게 되었습니다.

 

1. 1년 1월 1일은 월요일입니다. (2001년이 아닌, 말 그대로 "1년"입니다.)

2. 4년에 한 번씩 윤년이 껴있지만, 100년째 해는 4의 배수임에도 윤년이 아닙니다. 그러나 400년째 되는 해는 100의 배수임에도 윤년입니다.)

3. 즉,  서기 64년은 윤년이고, 서기 300년은 윤년이 아니고, 서기 800년은 윤년인 셈입니다. 올해인 2020년은 윤년이겠네요.

 

저는 1년 1월 1일 월요일부터 해서, 찾으시는 날짜가 있는 달의 첫 요일을 파악한 다음, 해당 요일부터 찾으시는 일 까지 몇 주가 지나는지 확인하는 방식으로 만들었습니다.

즉, 1월 13일 월요일을 확인하려면 ①1년 1월 1일부터 2020년 1월 1일까지 얼마나 지났나 파악하고, ②13번동안 일을 세며 주를 계산해야합니다.

 

그리하여 제가 쓴 코드는 아래와 같습니다.

year := 2020
Month := 2
Day := 20

WeekArr := ["월", "화", "수", "목", "금", "토", "일"]
MonthArr := [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

year -= 1
numOfDays := (year * 365) + (Year // 4) - (Year // 100) + (Year // 400) + 1

Loop, % Month - 1
	numOfDays += MonthArr[A_index]

if (Month >= 3 && (Mod((Year + 1), 4) = 0 && Mod((Year + 1), 100) != 0 || Mod((Year + 1), 400) = 0))
{
	numOfDays++
	MonthArr[2] += 1
}

StartDay := Mod(numOfDays, 7)
count := StartDay - 1
Week := 1

Loop, % day
{
	count++
	if (count = 8)
	{
		count := 1
		week++
	}
}
MsgBox, % WeekArr[count] "요일 `n" week "번째 주"

정말 복잡한데, 개행으로 끊어두었으니 하나씩 설명 드리겠습니다.

 

 

year := 2020
Month := 2
Day := 20

1. 위 구문은 사용자가 입력하는 "몇 번째 주인지 알고자 하는 날짜"를 입력하는 부분입니다.

 

WeekArr := ["월", "화", "수", "목", "금", "토", "일"]
MonthArr := [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

2. 두개의 배열을 생성합니다. 각각 "요일"과 "한 달의 일수"를 나타냈습니다.

 

year -= 1
numOfDays := (year * 365) + (Year // 4) - (Year // 100) + (Year // 400) + 1

3. 위와 같이, 윤년을 고려하여 1년 1월 1일부터 해당 해의 1월 1일까지의 일 수를 계산해줍니다.

 

Loop, % Month - 1
	numOfDays += MonthArr[A_index]

4. 찾으시는 달의 전 달 마지막 일까지 셉니다. 2월을 알고싶으면 1월 31일까지 날짜를 센 다는 뜻입니다.

3번 과정에서 1을 미리 더해주었으니, 그 다음 달 1일까지를 가져오겠네요.

 

 

if (Month >= 3 && (Mod((Year + 1), 4) = 0 && Mod((Year + 1), 100) != 0 || Mod((Year + 1), 400) = 0))
{
	numOfDays++
	MonthArr[2] += 1
}

5. 만약 찾고자 하는 달이 3월 이후에 있고, 윤년이라면 2월 29일을 고려해야하기 때문에 1일을 더해줍니다.

 

 

StartDay := Mod(numOfDays, 7)
count := StartDay - 1
Week := 1

6. 일수 계산을 위해 준비해줍니다. StartDay 변수는 시작 요일이며, 1은 월요일 7은 일요일입니다. (지금까지 세왔던 일수를 7로 나눈 것 뿐입니다.)

count변수는 그 달의 1일부터 수를 세면 "하루가 지났는데 2일"이 되어버리므로, 하나를 빼주어 "하루 지나면 1일, 이틀 지나면 2일..."로 계산을 편하게 하기 위함입니다. Week변수엔 드디어 우리가 찾고자 하는 "주"가 담길 예정이며, 0주라는 말은 없으므로 1주부터 시작합니다.

 

 

Loop, % day
{
	count++
	if (count = 8)
	{
		count := 1
		week++
	}
}
MsgBox, % WeekArr[count] "요일 `n" week "번째 주"

7. 끝입니다. Count가 7(일요일)을 넘어가면 다시 1(월요일)로 초기화 해주면서, 주를 한 주 더해줍니다.

 

MsgBox엔 찾고자 하는 날짜의 요일과 주차가 담기겠지요.

2020년 2월 20일은 4주차 목요일이고, 2024년 5월 31일은 5주차 금요일이겠네요.. ^^ (확인해보니 맞습니다.)

 

함수화 해서 사용하시는 것이 편하겠지요.

함수화해줍니다.

 

주차계산(year, month, day, byRef Yoil := 0)
{
	WeekArr := ["월", "화", "수", "목", "금", "토", "일"]
	MonthArr := [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

	year -= 1
	numOfDays := (year * 365) + (Year // 4) - (Year // 100) + (Year // 400) + 1

	Loop, % Month - 1
		numOfDays += MonthArr[A_index]

	if (Month >= 3 && (Mod((Year + 1), 4) = 0 && Mod((Year + 1), 100) != 0 || Mod((Year + 1), 400) = 0))
	{
		numOfDays++
		MonthArr[2] += 1
	}

	StartDay := Mod(numOfDays, 7)
	count := StartDay - 1
	Week := 1

	Loop, % day
	{
		count++
		if (count = 8)
		{
			count := 1
			week++
		}
	}
	Yoil := WeekArr[Count]
	return week
}

위와 같이 함수화 해주시면, 아래와 같이 사용해주시면 되겠네요.

 

MsgBox, % 주차계산(2020, 2, 20)

그리고 ByRef를 이용하여 출력변수를 구현했으므로, 아래처럼 쓰시면 요일 또한 계산하실 수 있습니다.

주차계산(2020, 2, 20, 요일)
MsgBox, %요일%

 

쉬워보여서 자신만만하게 지식IN에 해보겠다고 했는데, 의외로 헤맸습니다. 과정에서 1차이만 나도 반복된 나눗셈 때문에 결과는 크게 차이나서..

다른 분들도 관련 내용 구현하실때 참고해주세요.

    • 글자 크기

댓글 달기

서버에 요청 중입니다. 잠시만 기다려 주십시오...