대학생활 때 C언어로 재밌게 작성했던 요일 계산 프로그램을 작성해보자.
오랜만에 한가지 프로그램(아주 작은 프로그램이지만...)을 작성하는 것이라서 메소드에 대한 인수 판단 등의 각종 판단들이 잘 안서지만 그래도 연습차 한 번 작성해보았다.
1. 고려요소
가. 1년 1월 1일은 월요일이다.
나. 윤년은 4로 나눠떨어지는 연도 - 100으로 나눠떨어지는 연도 + 400으로 나눠떨어지는 연도이다(연도를 더하고 빼라는 것이 아닌 표현하자면...)
다. 윤년은 366일(2월이 기존 28일 -> 29일), 아닌 연도는 365일이다.
2. 구현
먼저 메인함수에서는 사용자로부터 연도, 월, 일을 입력받고 입력받은 정보를 토대로 Calendar 객체를 생성, 내부 메소드를 통해 요일을 계산해낸다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("연도를 입력하세요 >> ");
int year = in.nextInt();
System.out.print("월을 입력하세요 >> ");
int month = in.nextInt();
System.out.print("일을 입력하세요 >> ");
int day = in.nextInt();
Calendar c = new Calendar(year, month, day);
System.out.println("해당 날짜의 요일은 " + c.d_o_week() + " 입니다.");
}
}
Calendar 이라는 클래스 내에는 각종 메소드 등이 있고, 그 메소드들의 상호작용을 통해 d_o_week() 메소드를 동작, 결과물을 출력해낸다.
그렇다면 이번엔 Calendar 클래스를 보고 세부 내용을 보자.
public class Calendar {
private int year = 0;
private int month = 0;
private int day = 0;
private final String[] day_list = new String[]{"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
private final int[] month_day = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public Calendar(int y, int m, int d) {
this.year = y;
this.month = m;
this.day = d;
}
private boolean discri_leap(int check) {
if (check % 400 == 0) {
return true;
} else if (check % 100 == 0) {
return false;
} else {
return check % 4 == 0;
}
}
private int count_day() {
int count = 0;
int i;
for(i = 1; i < this.year; ++i) {
if (this.discri_leap(i)) {
count += 366;
} else {
count += 365;
}
}
for(i = 0; i < this.month; ++i) {
count += this.month_day[i];
if (i == 3 && this.discri_leap(this.year)) {
++count;
}
}
count += this.day;
return count;
}
public String d_o_week() {
int tmp = this.count_day();
return this.day_list[tmp % 7];
}
}
먼저 필드와 생성자 부분을 보자
public class Calendar {
private int year = 0;
private int month = 0;
private int day = 0;
private final String[] day_list = new String[]{"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
private final int[] month_day = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public Calendar(int y, int m, int d) {
this.year = y;
this.month = m;
this.day = d;
}
필드에는 year(연도), month(월), day(일), 요일리스트, 각 월별 일수가 있다. 그리고 생성자를 통해 세가지 필드(year, month, day)를 초기화 시킨다.
private boolean discri_leap(int check) {
if (check % 400 == 0) {
return true;
} else if (check % 100 == 0) {
return false;
} else {
return check % 4 == 0;
}
}
다음은 윤년 계산 메소드다. 고려대상에서 보았 듯 윤년은 4년주기로 찾아오며 그 중 100으로 나눠떨어지는 연도는 제외, 그리고 그 중에서 또 400으로 나눠지는 연도는 추가해주어야한다. 이중 포문으로 인한 시간 소요를 줄여주기 위해 반대로 적용을 하였다.
private int count_day() {
int count = 0;
int i;
for(i = 1; i < this.year; ++i) {
if (this.discri_leap(i)) {
count += 366;
} else {
count += 365;
}
}
for(i = 0; i < this.month; ++i) {
count += this.month_day[i];
if (i == 3 && this.discri_leap(this.year)) {
++count;
}
}
count += this.day;
return count;
}
다음은 사용자가 입력한 일자가 1년 1월 1일로부터 몇일이 지났는가를 계산해주는 메소드이다. 분명 i를 각 포문 안에서 선언해주었는데... 왜 밖으로 나와있지 싶은데 수정하기 귀찮으니...ㅎㅎ
예를 들어 입력한 날짜가 2년 2월 2일이라면
-> 1년의 날 수(365일)을 count에 모두 더해줌, 1월의 날 수(31일)를 모두 더해줌, 1일을 더해줌
과 같이 입력한 날짜까지 지나온 년수, 월수, 일수를 차례로 더해준다면 총 일 수가 나올 것이다.
다만 고려해야하는 것은 더하려고 하는 연도가 윤년인지 판단해야하고, 또 현재 연도의 2월을 더해줄 때 윤달인지 판단해서 더해줘야한다.
public String d_o_week() {
int tmp = this.count_day();
return this.day_list[tmp % 7];
}
마지막 메소드는 이전 메소드에서 모두 더해준 일수를 7로 나누어 해당 일자가 무슨요일인지 계산하는 메소드이다.
처음 필드에서 다음과 같은 필드를 정의해놓았으므로 7로 나누면 해당 요일이 나오는 것이다.
private final String[] day_list = new String[]{"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
이로써 끝. 결과물을 보자

'Language > JAVA' 카테고리의 다른 글
[JAVA] 미니프로젝트 - 자판기 프로그램(2) (0) | 2023.04.09 |
---|---|
[JAVA] 미니프로젝트 - 자판기 프로그램(1) (0) | 2023.04.03 |
[JAVA]반복문(1) - for문 (0) | 2022.10.01 |
[JAVA]조건문 - if, if-else문 (0) | 2022.09.27 |