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 |
---|