☕Java practice: Calendar app 만들기

yoondgu·2022년 3월 13일
0

Java practice

목록 보기
2/8
post-thumbnail

목표

자바를 통해 연도와 월을 입력받고, 달력을 출력하는 어플리케이션 만들기


프로그래밍 순서

  1. 연도, 월을 입력받는다.
    int year int month

  2. 해당 연도일 때 각 월의 최대일을 정한다. (배열 이용: 31,28,31,30...)
    int dayMax int dayData[]
    -이 때, 윤년의 2월 최대일은 하루가 더해짐을 고려한다.
    boolean isLeapYear
    윤년은 연도가 4의 배수이면서, 100의 배수가 아닐 때 또는 400의 배수일 때이다.

  3. 해당 월의 첫번째 날(1일)이 무슨 요일인지 알아낸다.
    -특정 포맷으로 입력할 경우 해당 날짜의 요일에 따른 정수값을 반환해주는 Calendar의 메소드를 이용한다.
    getFirstDay(String date, String dateType) int dayNum

  4. 첫번째 날(1일)을 기준으로 요일과 날짜가 알맞게 배치되도록 공백 출력을 설정한다.
    이 때 int dayNum 은 해당 월의 첫번째 날의 요일에 대한 정수값이다.

  5. 일자 출력에는 반복문을 이용하고, 주마다 줄바꿈하도록 설정하는 데는 if문을 이용한다.
    int day
    -주마다 줄바꿈하는 데에는 (day+dayNum-1)%7 == 0 일 때 day가 일요일이라는 것을 이용했다.

    Why?
    일요일의 정수값은 7일 때, day가 일요일일 경우 day+dayNum-1 은 7의 배수가 된다.
	dayNum은 1일이 요일이라는 7개의 칸 중 몇 칸을 비우는지를 알려주는 숫자이고,
    비우는 칸을 고려한 숫자를 더하면 지난 일요일로부터 7일이 지난 것이 되기 때문이다.

✔ 3번의 경우, 다른 분이 블로그에 올리신 소스코드를 이용해서 필요한 방식으로 조금 수정했다.
하지만 그래서 java.util.Date이나 java.text.SimpleDateFormat 과 같이 정확히 이해하지 못하고 있는 부분도 있다. 차차 공부할 것..!!!
✔ 일반적으로 첫 주의 시작을 일요일로 하는 달력을 만들고, Calendar 자체 기능에서도 일요일이 1값으로 반환되지만 개인적으로는 월요일을 시작으로 두고 싶어서 월요일을 1값으로, 일요일을 7값으로 수정했다.


소스코드

package MyCalendar;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class MyCalendarApp {
	
	public static int getFirstDay(String date, String dateType) throws Exception {
	     
	    SimpleDateFormat dateFormat = new SimpleDateFormat(dateType) ;
	    Date nDate = dateFormat.parse(date) ;
	     
	    Calendar cal = Calendar.getInstance() ;
	    cal.setTime(nDate);
	     
	    int dayNum = cal.get(Calendar.DAY_OF_WEEK) ;
	    // Calndar.DAY_OF_WEEK은 일~월 순으로 1부터 값을 반환하나 편의상 월요일을 1값으로 변경하기 위해 아래 제어문을 설정함.
	    if (dayNum == 1) {
	    	dayNum = 7;
	    } else {
	    	dayNum -= 1;
	    }
	    return dayNum;
	     
	}

	public static void main(String[] args) throws Exception {
		
		// 요청 날짜 받기
		Scanner sc = new Scanner(System.in);
		
		System.out.print("연도를 입력하세요. ");
		int year = sc.nextInt();
		if (year < 0) {
			System.out.print("자연수로 입력하세요. ");
			year = sc.nextInt();
		}
		
		System.out.print("월을 입력하세요. ");
		int month = sc.nextInt();
		if (month < 0 || month > 12) {
			System.out.print("12 이하의 자연수로 입력하세요. ");
			month = sc.nextInt();
		}
		sc.close();
		
		// 윤년 계산
		int dayMax = 0;
		int dayData[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
		boolean isLeapYear = year%4 == 0 && (year%100 !=0 || year%400 ==0);
		
		if (isLeapYear && month == 2) {
			dayMax = dayData[month-1] + 1;
		}
		if ((isLeapYear && month != 2) || isLeapYear == false) {
			dayMax = dayData[month-1];
		}
		
		// 요일 계산을 위한 변수 설정
		int day = 1;
		String yearStr = String.valueOf(year);
		String monthStr = String.valueOf(month);
		String dayStr = String.valueOf(day);
		String inputDay = yearStr + "-" + monthStr + "-" + dayStr;
		int dayNum = getFirstDay(inputDay, "yyyy-MM-dd");
		
		// 달력 형식 텍스트 출력
		// 이모지 출력: 
		System.out.println();
		System.out.println(" ⛅⛅⛅⛅ " + yearStr + "-" + monthStr + " ⛅⛅⛅⛅");
		System.out.println("MON TUE WED THU FRI SAT SUN");

		// 요일의 위치에 맞게 일자가 시작되도록, 1일의 요일값(dayNum)에 따라 입력 회수를 설정하여 공백을 출력한다.
		// dayNum은 DayNum.getFirstDay() 에서 월: 1 ~ 일:7 로 지정함.
		for (int i = 0; i < dayNum; i++) {
			if (i > 0) {
				System.out.print("    ");
			}
		}
		
		// 날짜 전체 출력하기
		// 1~ daymax까지 반복문을 통해 출력한다.
		// 이 때 일요일이 지나면 줄바꿈하도록 한다. (day+dayNum-1)%7 == 0
		// 두자리 수는 공백을 한 자리만 쓰도록 한다.
		for (day = 1; day <= dayMax; day++) {
			if (day < 10) {
				System.out.print(" " + day + "  ");
			} else {
				System.out.print(day + "  ");
			}
			if ((day+dayNum-1)%7 == 0) {
				System.out.print("\n");
			}
		}

	}

}

출력 내용

✔ 아래와 같이 연도, 월에 잘못된 수를 적으면 다시 입력하게끔 하였다.
✔ 윤년일 때 2월달의 날짜가 적용되었다.

연도를 입력하세요. -1
자연수로 입력하세요. 2012
월을 입력하세요. 13
12 이하의 자연수로 입력하세요. 2

 ⛅⛅⛅⛅ 2012-2 ⛅⛅⛅⛅
MON TUE WED THU FRI SAT SUN
         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  

✔ 올바른 수를 입력했을 경우.

연도를 입력하세요. 2022
월을 입력하세요. 3

 ⛅⛅⛅⛅ 2022-3 ⛅⛅⛅⛅
MON TUE WED THU FRI SAT SUN
     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  31  

참고한 자료

Java 오늘 날짜 출력하기
캘린더 클래스 이용해서 말일 구하기
달력의 요일 구하는 법

0개의 댓글