[Java] 배열과 Calendar 클래스로 달력 출력하기-입력 받아 출력, 가로로 두 개 출력

2021. 3. 23. 15:41·Programming/JAVA

 

 

1. 입력한 달의 달력 출력 (배열)

int y, m;			//--입력받을 연, 월 변수
int d;				//--입력받은 달의 1일이 무슨 요일에 시작하는지 알아내기 위해 쓸 변수
int start;			//--입력받은 달의 1일이 무슨 요일에 시작하는지 알아낸 변수
int last;			//--입력받은 달이 며칠까지 있는지 알아낼 변수
int n=1;			//--달력에 숫자를 넣어줄 변수
String blank = " ";	//--1일 이전의 자리에 공백을 넣을 변수
String[][] arr = new String[6][7];	//--공백을 담기 위해 String배열로 생성

int[] days = {31,28,31,30,31,30,31,31,30,31,30,31};
		
Scanner sc = new Scanner(System.in);

do
{
	System.out.print("연도 입력:  ");
	y = sc.nextInt();
}
while (y < 1);

do
{
	System.out.print("월 입력:  ");
	m = sc.nextInt();
}
while (m < 1 || m >12);
		

if (y % 4 == 0 && y % 100 !=0 || y % 400 == 0)
	days[1] = 29;

d = (y-1)*365 + (y-1)/4 - (y-1)/100 + (y-1)/400;

for (int i=0; i<m-1; i++)
	d += days[i];
			
d += 1;

start = d % 7;		//--입력받은 달의 1일이 무슨 요일에 시작하는지
last = days[m-1];	//--입력받은 달이 며칠에 끝나는지
		
for (int j=0; j<arr[0].length; j++)		//--첫 번째 줄
{
	if (j<start)
		arr[0][j] = blank;
	else
	{
		arr[0][j] = Integer.toString(n);
		n++;
	}
}

for (int i=1; i<arr.length; i++)		//--두 번째 줄부터 끝까지
{
	for (int j=0; j<arr[i].length; j++)
	{
		if (n<=last)		
		{
			arr[i][j] = Integer.toString(n);
			n++;
		}
        else
			arr[i][j] = blank;
	}
}

System.out.printf("\n    [ %d년 %d월 ]\n\n", y, m);
System.out.println(" 일 월 화 수 목 금 토 ");
System.out.println("======================");
			
int cut = 0;		//--달력의 마지막 줄이 공백이면 삭제하기 위한 변수

if (start < 5)		//--1일이 토요일 이전에 시작하면 삭제
	cut++;
else if (m == 2)	//--위에 해당하지 않는 경우에도 2월이면 삭제
	cut++;

for (int i=0; i<arr.length-cut; i++)
{
	for (int j=0; j<arr[i].length; j++)
		System.out.printf("%3s", arr[i][j]);
	System.out.println();
}

System.out.println("======================");

 

[실행 예시]

 

 

2. 달력 가로로 두 개 출력 (Calendar 클래스)

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;


class Calendartwo
{
	public static void main(String[] args)
	{
		int w1, w1Check, w2, last, last2, last2Check, y, m, n7, n2Check;
		int d = 1, n1 = 1, n2 = 1;
		boolean flag1 = false, flag2 = false;
		
		Scanner sc = new Scanner(System.in);
		
		do
		{
			System.out.print("연도 입력: ");
			y = sc.nextInt();
		}
		while (y<1 || y>2021);

		do
		{
			System.out.print("달 입력: ");
			m = sc.nextInt();
		}
		while (m<1 || m>12);

		System.out.println();	//--편의상 개행

		// 왼쪽 달력(입력받은 달) 설정
		Calendar cal1 = new GregorianCalendar();
		cal1.set(y,m-1,1);								//--입력받은 연도와 월의 1일로 설정
		w1 = cal1.get(Calendar.DAY_OF_WEEK);			//--1일이 해당하는 요일(일요일: 1)
		w1Check = w1;									//--w 값이 변동 없도록 따로 담아둘 변수
		last = cal1.getActualMaximum(Calendar.DATE);	//--날짜 최대값(마지막 날)

		// 오른쪽 달력(입력받은 달의 다음 달) 설정
		Calendar cal2 = new GregorianCalendar();
		cal2.set(y,m,1);
		w2 = cal2.get(Calendar.DAY_OF_WEEK);
		last2 = cal2.getActualMaximum(Calendar.DATE);
		last2Check = last2;
		
		if (m < 12)
			System.out.printf("        [%d년 %d월]\t\t\t   [%d년 %d월]",y,m,y,m+1);
		// 입력한 달의 다음 달이 1월인 경우 13월으로 출력되지 않도록 한다.
		else
			System.out.printf("        [%d년 %d월]\t\t\t   [%d년 %d월]",y,m,y,1);

		System.out.print("\n\n 일  월  화  수  목  금  토         일  월  화  수  목  금  토\n============================       ============================\n");
		

		// 왼쪽 달력 1일 이전의 공백 출력
		for (int i=1; i<w1; i++)
		{
			System.out.print("    ");
			n1++;
		}
		
		// 7*6, 즉 7일만큼의 6주를 만들기 위해 42칸을 배정한다.
		for (int i=1; i<=42; i++)
		{	
			// 왼쪽 달력 채우기
			// 마지막 일까지 숫자 채웠으면 남은 칸은 공백으로 채우기
			if (d <= last)
			{
				System.out.printf("%4d", d);
				d++;
				n1++;
			}
			else if (n1 <= 35)
			{
				flag1 = true;
				System.out.printf("    ");
				n1++;
			}
			else if (n1 <= 42 && last+w1Check != 36)
			{
				if (!flag1)
				{
					System.out.printf("    ");
					n1++;
				}
				else 
				{
					System.out.printf("====");
					n1++;
				}
			}
			else if (n1 <= 42)
			{
				// 2021년 7월처럼 마지막 요일에 마지막 일이 오는 경우를 위함
				flag1 = true;
				System.out.printf("====");
				n1++;
			}

			// 오른쪽 달력 첫째 주
			// 달력을 한 개만 출력할 때에는 이때 개행을 하면 되는데
			// 가로로 두 개를 출력할 때에는 개행이 아니라
			// 이어서 오른쪽 달력을 한 줄씩 출력한다.
			if (w1 == 7)
			{
				System.out.printf("       ");

				for (int j=1; j<w2; j++)
				{
					System.out.print("    ");
					last2Check++;
				}
				
				// 해당 달의 1일이 위치하는 요일(w2)을 첫째 주(일주일, 7)에 해당하는 만큼만
				// 출력하기 위해 7-w2를 하는데, 이때 w2는 0이 아닌 1부터 시작하므로
				// 7-(w2-1), 즉 8-w2를 조건식으로 둔다.
				for (int j=1; j<=8-w2; j++)
				{
					System.out.printf("%4d", j);
					// 오른쪽 달력 날짜를 저장하는 변수 n은 다음 주부터 써야 하므로
					// 지금 출력하지 않더라도
					// j로 일수가 출력될 때마다 함께 증가시킨다.
					n2++;
				}
			}

			// 오른쪽 달력 둘째, 셋째, 넷째, 다섯째 주
			if (w1 == 14 || w1 == 21 || w1 == 28 || w1 == 35)
			{
				System.out.printf("       ");
				
				// 한 주에 해당하는 일만 출력하기 위해
				// n에 7을 더한 값까지만 출력할 수 있도록 한다.
				n7 = n2+7;

				for (int j=n2; j<n7; j++)
				{
					System.out.printf("%4d", j);
					// 다섯째 주의 경우에는 마지막 일까지 출력되고
					// 뒤는 공백으로 남겨야 할 경우
					// n7까지 출력하면 안 되므로 break를 건다.
					if (j==last2)
						break;
					// 여섯째 주까지 출력하게 될 수도 있으므로
					// n은 계속해서 증가시킨다.
					n2++;
				}
			}

			// 오른쪽 달력 여섯째 주
			if (w1 == 42)
			{
				System.out.printf("       ");
				
				n2Check = n2;

				// 만약 다섯째 주의 마지막에 오는 일(n)이
				// 해당 달의 마지막 일(last2)보다 작으면
				// 여섯째 주에 last2까지의 일을 더 출력해야 한다.
				if (n2<last2)
				{
					for (int j=n2; j<=last2; j++)
					{
						if (n2<=last2)
							System.out.printf("%4d", j);
						n2Check++;
					}
				}
				else
				{
					// 오른쪽 달력의 여섯째 주에 출력할 일이 없으면
					// 달력구분선을 출력한다.
					flag2 = true;
					System.out.print("============================");
				}
				
				// 만약 여섯째 주에 오른쪽 달력은 달력 구분선이 출력되지 않았고
				// 왼쪽 달력은 달력이 이미 출력됐을 경우
				// 그 다음 줄에 달력 구분선을 출력하기 위해
				// 오른쪽 달력의 여섯째 주 공백과 그 다음 줄에서 왼쪽 달력이 해당하는 만큼의 공백을 채워준다.
				if (flag1 && n2Check != last2)
				{
					for (int j=0; j<42-last2Check; j++)
						System.out.print("    ");
					System.out.println();
					for (int j=0; j<7; j++)
						System.out.print("    ");
				}
			}

			// 오른쪽 달력까지 출력한 뒤 개행한다.
			// 단, 42칸(마지막 주) 째에는 개행되지 않도록 한다.
			if (w1%7 == 0 && w1 != 42)
				System.out.println();
			
			// 만약 왼쪽 달력 다섯째 주에 달력 구분선이 출력되지 않았을 경우
			// 42칸 째에도 개행한다.
			if (!flag1 && w1 == 42)
				System.out.println();
			
			w1++;
		}
		
		// 만약 왼쪽 달력 다섯째 주에 달력 구분선이 출력되지 않았을 경우
		// 여섯째 주의 다음 줄에 출력한다.
		if (!flag1)
			System.out.print("============================\n");
		
		if (!flag2)
			System.out.print("       ============================\n");
		
		if (flag1)
			System.out.println();	//--편의상 개행
		
		if (flag2)
			System.out.println();	//--편의상 개행

	}
}

 

[실행 예시]

* 실행 예시에선 요일 위치가 살짝 안 맞게 나오는데 제대로 나오는 거 맞다. 수정하기 귀찮아서 냅뒀지만 언젠간 고칠 것...

 

 

오늘의 깨달음: 나는 왜 괜히 달력 밑에 구분선을 붙여 출력하고 싶어서... 달력은 참 변수가 많다.

오늘의 궁금증: 미래에서 이 글 보면 얼마나 까마득할까?

 

 

'Programming > JAVA' 카테고리의 다른 글

[Java] 별 찍기-삼각형, 피라미드, 마름모  (0) 2021.02.20
'Programming/JAVA' 카테고리의 다른 글
  • [Java] 별 찍기-삼각형, 피라미드, 마름모
NPC
NPC
예... 안녕하세요
어떤 블로그의 겁나 옛날 글예... 안녕하세요
  • NPC
    어떤 블로그의 겁나 옛날 글
    NPC
  • 전체
    오늘
    어제
    • 분류 전체보기 (20)
      • MEMO (3)
      • Programming (3)
        • JAVA (2)
        • PYTHON (1)
      • Coding Test (7)
        • Programmers (7)
      • REST API (3)
      • ERROR (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    AttributeError
    Ngrok
    웹크롤링
    git명령어
    카카오로그인
    500에러
    자바예제
    illegalStateException
    15Z970
    LG그램
    배터리수명
    restfulapi
    beautifulsoup4
    java
    코딩테스트
    sqlexception
    자바달력예제
    카카오로그인API
    myBatis
    sns로그인
    15z970-ga5bk
    level1
    Python
    BindingException
    카카오
    카카오로그아웃
    level2
    프로그래머스
    restapi
    별찍기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
NPC
[Java] 배열과 Calendar 클래스로 달력 출력하기-입력 받아 출력, 가로로 두 개 출력
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.