캘린더 1에서 만들어본 달력에 기능을 추가해서 더 정교한 달력을 만들어 보도록 하겠습니다.
시작하는 날짜의 요일을 입력하는 달력만들기
다음 결과 값 같이 첫번째 요일을 입력하여 그 날을 기준으로 1일을 시작하는 달력을 만들어 보겠습니다.
연도를 입력하세요.(exit: -1)
YEAR> 2020
달을 입력하세요:
MONTH> 2
첫번째 요일을 선택하세요. (su, mo, tu, we, th, fr, sa
DAY> tu
<<2020년 2월>>
SU MO TU WE TU FR SA
----------------------
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
연도를 입력하세요.(exit: -1)
YEAR>
public class Prompt {
public int parseDay(String week) {
if (week.equals("su")) return 0;
else if (week.equals("mo")) return 1;
else if (week.equals("tu")) return 2;
else if (week.equals("we")) return 3;
else if (week.equals("th")) return 4;
else if (week.equals("fr")) return 5;
else if (week.equals("sa")) return 6;
else
return 0;
}
public void runPrompt() {
Scanner scanner = new Scanner(System.in);
Calendar cal = new Calendar();
int month = 1;
int year = 2020;
int weekday = 0;
for (;;) {
System.out.println("연도를 입력하세요.(exit: -1)");
System.out.print("YEAR> ");
year = scanner.nextInt();
if (year == -1) {
break;
}
System.out.println("월을 입력하세요:");
System.out.print("MONTH> ");
month = scanner.nextInt();
System.out.println("첫번째 요일을 선택하세요. (su, mo, tu, we, th, fr, sa");
System.out.print("DAY> ");
String str_weekday = scanner.next();
weekday = parseDay(str_weekday);
if (month >12 || month <1) {
System.out.println("잘못된 입력 입니다.");
continue;
} else {
cal.printCalendar(year, month, weekday);;
System.out.println("");
}
}
System.out.println("bye~");
scanner.close();
}
public static void main(String[] args) {
// 셀 실행
Prompt p = new Prompt();
p.runPrompt();
}
}
시작 요일을 입력받기 위해 Prompt 클래스에서 월을 입력하는 곳 밑에 첫번재 요일을 String str_weekday 변수로 입력을 받습니다.
String형 자료를 int형으로 변경하기 위한 parseDay라는 메소드를 만들어주고 weekday변수에 담아줍니다.
public class Calendar {
private static final int[] MaxDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static final int[] LeapMaxDays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
public static boolean isLeapYear(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return true;
else
return false;
}
public static int getMaxDaysOfMonth(int year, int month) {
if (isLeapYear(year))
return LeapMaxDays[month - 1];
else
return MaxDays[month - 1];
}
public void printCalendar(int year, int month, int weekday) {
System.out.printf(" <<%4d년%3d월>>\n", year, month);
System.out.println(" SU MO TU WE TU FR SA");
System.out.println("----------------------");
for (int i = 0; i < weekday; i++) {
System.out.print(" ");
}
int maxDay = getMaxDaysOfMonth(year, month);
int count = 7 - weekday;
int delim = (count < 7)? count:0;
for(int i = 1; i <= count; i++) {
System.out.printf("%3d", i);
}
System.out.println();
for (int j = count+1; j <= maxDay; j++) {
System.out.printf("%3d", j);
if (j % 7 == delim) {
System.out.println();
}
}
System.out.println();
}
}
Calendar클래스로 돌아와 시작하는 요일에 맞추기 위해 weekday만큼 공백을 넣어주는 반복문을 만들어줍니다.
첫째줄이 달력밖으로 튀어나오는 현상을 고쳐주기 위해 첫 줄만 출력하는 반복문을 만들어주고 범위를 int count = 7- weekday라는 변수를 통해 지정해줍니다.
두번째 줄부터 마지막까지 출력하는 반복문을 하나더 만들어 초기값을 count+1로 잡아주면 첫줄에서 출력하지 못한 숫자부터 최대수까지 출력하게 됩니다.
출력해보면 출력되는 수는 이제 문제가 없지만 기존에 7의 배수에서 줄바꿈을 하도록 작성되었기에 줄바꿈이 엉망인것을 알수 있습니다. 그것을 해결하기 위해 반복문 안에 if(j%7 == count)을 if(j % 7 == count)로 고치면 알맞게 줄바뀜이 되는 것을 알 수 있습니다.
요일에 su를 입력할 경우 count=7이되어 오류가 발생하게 되기 때문에 delim이라는 변수를 만들고 삼항연산자로 간단한 조건문을 작성해 count>7 인경우 0이 될 수 있게 설정해주면 문제없이 결과값이 나오게 됩니다.
마지막으로 입력값의 범위를 지정해주기 위해 Prompt 클래스에서 year 변수값 받는 곳 밑에 break문을 넣어주고 아래의 다시 month의 범위를 지정해주고 continue문을 넣어주면 입력값의 범위를 지정할 수 있습니다.
그 뒤 실행해보면 결과값이 나오는 것을 확인할 수 있습니다.