국비교육/국비교육 복습

Day04_condition2_Test04 : 윤년 계산 (★)

Luver Duck 2022. 7. 31. 20:37

(Q) 사용자에게 연도와 월을 입력받아서 날짜 수를 구하는 프로그램을 구현

윤년

실제 지구가 태양을 공전하여 시작점으로 회귀하는데 걸리는 시간은 약 365일 + 6시간
4년동안 지구가 태양을 공전하는데 걸리는 실제 시간은 약 365*4일 + 1일
2월을 28일로 정할 때 4년마다 실제 지구가 태양을 공전한 시간과 율리우스력 사이의 오차를 보정하기 위해

2월에 1일을 추가해야 하는 년도
- 평년 : 2월의 날짜가 28일인 해
- 윤년 : 2월의 날짜가 29일인 해 


정리하면
1. 연도가 4의 배수이면 윤년이다 (ex : 2020, 2024, 2028년은 윤년)
2. 4의 배수이지만 100의 배수이면 윤년이 아니다 (ex : 2100년은 윤년이 아니다)
3. 2번에 해당되더라도 400의 배수이면 윤년이다 (ex : 2000년은 윤년)

 

package condition2;

import java.lang.*;

import java.util.Scanner;

public class Test04_me {
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		System.out.println("년도를 입력하세요");
		int year = sc.nextInt();
		
		System.out.println("월을 입력하세요");
		int month = sc.nextInt();
		
		sc.close();
		
		int logic1 = year % 4;
		
		
		int logic3TF;
		switch(logic1) {
		case 0:
			int logic2 = year % 100;
			switch(logic2) {
			case 0:
				if(year % 400 == 0) {
					System.out.println(year + "년은 윤년이 맞습니다");
					logic3TF = 1;
				}
				else {
					System.out.println(year + "년은 윤년이 아닙니다");
					logic3TF = 0;
				}
				break;
			default:
				System.out.println(year + "년은 윤년이 맞습니다");
				logic3TF = 1;
				break;
			}
			
			break;
			
		default:
			System.out.println(year + "년은 윤년이 아닙니다");
			logic3TF = 0;
		}
		
		switch(month) {
		case 4: case 6: case 9: case 11:
			System.out.println(month + "월의 일 수는 30일 입니다");
			break;
		case 1: case 3: case 5: case 7: case 8: case 10: case 12:
			System.out.println(month + "월의 일 수는 31일 입니다");
			break;
		case 2:
			if(logic3TF == 0) {
				System.out.println(month + "월의 일 수는 28일 입니다");
			}
			else {
				System.out.println(month + "월의 일 수는 총 29일 입니다");
			}
		}
		
	}

}

 

** 부족했던 점

1) switch를 두 번 사용하여 한 번은 윤년 판정에, 한 번은 월 판정에 씀으로써 중복 코드 발생

2) 윤년 판정은 2월에 대해서만 하면 된다 

 

 

 

 

** 부족했던 점 보충 1차

- 윤년일 경우 2월의 일수만 바뀐다 (다른 달에 대해서는 윤년 판정을 고려할 필요가 없다)

- switch ~ case 문으로 일수가 달라지는 2월과 30일인 달을 구분하고 31일인 달은 default로 하는 것이 좋다

package day04;

import java.lang.*;

public class Day04_condition2_Test04_problem {

	public static void main(String[] args) {
		
		int year = 2000;
		int month = 2;
		
		int day;
		switch(month) {
		case 2:
			if(year % 4 == 0) {
				if(year % 100 != 0) {
					day = 29;
				}
				else if(year % 100 == 0){
					if(year % 400 == 0) {
						day = 29;
					}
					else {
						day = 28;
					}
				}
				else {
					day = 28;
				}
			}
			else {
				day = 28;
			}
			break;
		case 4: case 6: case 9: case 11:
			day = 30;
			break;
		default :
			day = 31;
			break;
		}
		
		System.out.println(year + "년 " + month + "월은 총 " + day + "일까지 있습니다");
		
		
	}
	
}

 

 

 

** 부족했던 점 보충 2차

- boolean으로 윤년인 조건을 한번에 ||(and)로 연결하여 T/F를 알 수 있는 논리식을 구성

package day04;

import java.lang.*;

public class Day04_condition2_Test04_1 {

	public static void main(String[] args) {
		
		int year = 2100;
		int month = 2;
		
		boolean leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
		
		int day;
		switch(month) {
		case 2:
			if(leap) {
				day = 29;
			}
			else {
				day = 28;
			}
			break;
		case 4: case 6: case 9: case 11:
			day = 30;
			break;
		default :
			day = 31;
			break;
		}
		
		System.out.println(year + "년 " + month + "월은 총 " + day + "일까지 있습니다");
		
	}
	
}

 

 

 

 

** 벤 다이어그램?

노란색 영역에 속하면 윤년

- year % 4 == 0이 true라면 x4 안의 영역 / 그렇지 않다면 x4 밖의 영역

- x4 경계 안에서 year % 100 == 0이 true라면 x100 안의 영역 / 그렇지 않다면 x100의 밖의 영역

- x100 경계 안에서 year % 400 == 0이 true라면 x400 안의 영역 / 그렇지 않다면 x400의 밖의 영역