Everything has an expiration date
★ 105 - Java 만년 달력 : 사용자가 입력한 년도와 월의 달력을 출력하는 프로그램 ( + 메모장으로 작성한 소스...) 본문
[Java]/review
★ 105 - Java 만년 달력 : 사용자가 입력한 년도와 월의 달력을 출력하는 프로그램 ( + 메모장으로 작성한 소스...)
Jelly-fish 2023. 9. 11. 15:20/*=============================================
■■■ 만년 달력 ■■■
- 다음과 같은 기능의 프로그램을 구현한다.
===============================================*/
// 실행 예)
// 『연도』를 입력하세요 : 2023
// 『월』을 입력하세요 : 9
/*
[ 2023년 9월 ]
일 월 화 수 목 금 토
============================
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
============================
계속하려면 아무 키나 누르세요...
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Test105
{
public static void main(String[] args) throws IOException
{
// BufferedReader 인스턴스 생성
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 배열 선언 및 초기화
//-- 각 달이 담고있는 마지막 날짜(매 월의 최대 날짜)
int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 월 1 2 3 4 5 6 7 8 9 10 11 12
// 확인
//System.out.println(days.length);
// 주요 변수 선언
int nalsu, y, m, w; //-- 날 수, 년, 월, 요일
do
{
System.out.print("『연도』를 입력하세요 : ");
y = Integer.parseInt(br.readLine());
}
while (y < 1);
//-- 입력받은 연도가 1보다 작을 경우 다시 입력받기~!!!
do
{
System.out.print("『월』을 입력하세요 : ");
m = Integer.parseInt(br.readLine());
}
while (m < 1 || m > 12);
//-- 입력받은 월이 1보다 작거나 12보다 큰 경우 다시 입력받기~!!!
//---------------- 여기까지 수행하면 유효한 연도와 월을 사용자로부터 입력받은 상태
// 입력받은 연도에 해당하는 2월의 마지막 날 계산
if ((y%4==0) && (y%100!=0) || (y%400==0)) //-- 윤년이라면...
{
days[1] = 29;
}
// else 구문은
// 현재 days 배열의 1번째 요소(2월)가 28일로 구성되어 있는 상태이기 때문에
// 생략이 가능한 구문이 된다.
// 1년 1월 1일 ~ 입력받은 연도의 이전 년도 12월 31일 까지의 날 수 계산
nalsu = (y-1)*365 + (y-1)/4 - (y-1)/100 + (y-1)/400;
// 입력받은 연도(해당 연도) 1월 1일 ~ 입력한 월의 이전 월까지의 날 수 계산
for (int i = 0; i < (m-1); i++)
{
nalsu += days[i];
}
// 입력받은 월의 1일을 날 수 누적 연산
nalsu += 1; // ++nalsu;
//------------------------------------------ 여기까지 수행하면 모든 날 수에 대한 종합 처리 완료
// 요일 확인
//-- 입력받은 연의 입력월의 1일이 무슨 요일인지 확인하기 위한 연산
w = nalsu % 7;
//-- w:0 → 일요일
//-- w:1 → 월요일
//-- w:2 → 화요일
//-- w:3 → 수요일
//-- w:4 → 목요일
//-- w:5 → 금요일
//-- w:6 → 토요일
// 확인
//System.out.println("w : " + w);
//--==>> 『연도』를 입력하세요 : 2024
// 『월』을 입력하세요 : 5
// w : 3
// 2024년 5월 1일은 수요일(3)이라는 의미
//------------------------------------------ 여기까지 수행하면 해당 연도 해당 월의 1일이 무슨 요일인지 확인 완료.
// 출력(달력 그리기)
System.out.println(); //-- 개행
System.out.printf("\t[ %d년 %d월 ]\n", y, m);
System.out.println(); //-- 개행
System.out.println(" 일 월 화 수 목 금 토"); //-- 하루 4칸
System.out.println("============================");
// 특정 요일부터 1일이 출발할 수 있도록 공백 발생(지정)
for (int i = 1; i <= w; i++)
{
System.out.print(" "); //-- 공백 4칸 지정
}
// 확인
//System.out.printf("%4d", 1);
// 해당 월(입력한 월)의 날짜만 출력될 수 있도록 반복문 구성
for (int i = 1; i <= days[m-1]; i++)
{
System.out.printf("%4d", i);
w++;
//-- 반복문을 통해 날짜를 처리하는 동안
// 그만큼의 요일도 함께 증가할 수 있도록 처리~!!!
// 일요일을 구성하려는 경우...
// (즉, 이번에 출력하고자 하는 날짜가 일요일인 경우...)
if (w%7==0)
{
// 개행
System.out.println();
}
}
// 달의 마지막 날짜가 출력 형식을 모두 채웠을 경우
// (즉, 토요일까지 라인 전체 출력이 이루어졌을 경우)
// 이미 일요일 개행이 이루어졌기 때문에
// 이 경우에는 추가 개행을 하지 않도록 처리~!!!
if (w % 7 != 0)
{
System.out.println();
}
System.out.println("============================");
}
}
// 실행 결과
/*
『연도』를 입력하세요 : 2023
『월』을 입력하세요 : 9
[ 2023년 9월 ]
일 월 화 수 목 금 토
============================
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
============================
계속하려면 아무 키나 누르십시오 . . .
*/
/*
『연도』를 입력하세요 : 2024
『월』을 입력하세요 : 8
[ 2024년 8월 ]
일 월 화 수 목 금 토
============================
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 일요일이 아닐 때만 개행해라! → w % 7 != 0;
<일요일일 때 개행을 했는데, 다시 개행을 해서 이렇게 됨...>
============================
계속하려면 아무 키나 누르십시오 . . .
*/
메모장에 새로 다시 짜본 source - 오류 얼마나 나는지 체크해보자... 😥😫😓😱
import java.util.Scanner;
public class Review105
{
public static void main(String[] args)
{
// 1. 변수 선언
Scanner sc = new Scanner(System.in);
int inputYear, inputMonth;
int sumYear, sumMonth;
int totalDay;
int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int n = 1;
int dayOfweek;
// 2. 입력 받기 (Scanner)
System.out.print("『 연도 』 입력 : ");
inputYear = sc.nextInt();
System.out.print("『 월 』 입력 : " );
inputMonth = sc.nextInt();
// 3. 입력받은 연도가 윤년이면? 월의 마지막 날 배열 monthDays의
// 2월달 월의 수 monthDays[1] = 29;로 변경.
if ((inputYear % 4 == 0) && (inputYear % 100 != 0) || (inputYear % 400 == 0))
{
monthDays[1] = 29;
}
// 4. 입력받은 연도의 전년도까지의 총 일수를 더하여 sumYear에 저장.
sumYear = (inputYear-1)*365 + (inputYear-1)/4 - (inputYear-1)/100 + (inputYear-1)/400;
// 전년도가 전부 평일이라고 가정하고 [ 전년도 * 365 ] + 4의 배수인 연도일 때(윤년) 1을 더함
// + 100의 배수인 연도일 때는 1을 뺌. + 400의 배수인 연도에는 더함.
// 5. 입력받은 월의 전 월까지의 총 일수를 더하여 sumMonth에 저장.
for(int i = 0; i < inputMonth-1 ; i++)
{
sumMonth += monthDays[i];
}
// 6. 전년도 일수 + 전 월 일수 + 1을 하여(구하려는 건 사용자가 입력한 달의 1일이므로)
// totalDay에 저장.
totalDay = sumYear + sumMonth + 1;
// 7. 총 일수를 7로 나누어 요일을 알 수 있도록 dayOfWeek에 저장.
dayOfWeek = totalDay % 7;
// 8. 요일을 알았으므로... 이제 본격적인 달력 출력 시작!!
for(int i = 0; i < dayOfWeek ; i++)
{
System.out.print(" "); // 만약, 출력하는 1일의 요일이 금요일이면 5번 공백을 넣고 출력 시작.
}
// i는 요일의 수(0:일, 1:월, 2:화, ...)부터, 입력받은 달(monthDays[inputMonth-1])의 마지막 날까지 반복)
for(int i = dayOfWeek ; i < monthDays[inputMonth-1] ; i++)
{
System.out.printf("%4d", n); // n은 일수를 찍기 위해 1부터 1씩 증가함.
dayOfWeek++
if(dayOfWeek % 7 == 0) // 만약, 일요일이면...
{
System.out.println(); // 개행!
}//end for if
}//end for i
if(dayOfWeek % 7 != 0) // 출력을 종료했을 때 일요일이 아니라면
{
System.out.println(); // 개행하시오!!
// 왜냐면... 달의 마지막 날이 일요일일 때
} // 마지막 출력까지 for문을 돌면서 이미 한번 개행한 상태인데
// for문을 끝나고 나서도 다 개행해줘 버리면
// 한 줄을 더 띄게 되니까... 빈 줄이 한 줄 생겨버려...
}//end main()
}//end Review105