#include <stdio.h>
#include <windows.h>
#include <wincon.h>
#include <conio.h>
#define DEFAULT_YEAR 2008
#define DEFAULT_MONTH 3
#define ESC 0x1b
#define UP 0x48
#define DOWN 0x50
#define LEFT 0x4b
#define RIGHT 0x4d
// 0 : 평년
// 그 외 : 윤년
int isLeapYear(int year) {
return ((year % 4 == 0 && year % 100) || year % 400 == 0);
}
void gotoxy(int x, int y) {
OORD Pos = { x - 1, y - 1 };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}
void blue() {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
}
void red() {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
}
void white() {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
int calculateDays(int year, int month) {
int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int i, days = 1;
// 인자로 받은 전년도까지 일수 구하고
for (i = 1; i < year; i++) {
days += 365;
if (isLeapYear(i))
days++;
}
// 인자로 받은 전달까지 일수를 구한 후에
for (i = 1; i < month; i++) {
days += month_days[i - 1];
if (i == 2 && isLeapYear(year))
days++;
}
// 구한 일수를 리턴
return days;
}
void printCalendar(int year, int month) {
int i, j;
int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int days = calculateDays(year, month);
if (!days) {
printf("달력을 출력할 수 없습니다!");
return;
}
// 윤년인 경우 달력 출력시 1일 추가
if (isLeapYear(year))
month_days[1] += 1;
white();
printf(" [ %4d.%02d ]\n", year, month);
printf("-----------------------------------\n");
printf("SUN MON TUE WED THU FRI SAT \n");
printf("-----------------------------------\n");
// 첫날 시작 요일 전까지 공백 찍어줌
for (i = 0, j = (days) % 7; i < j; i++) {
printf(" ");
}
// 요일 출력
for (i = 1; i <= month_days[month - 1]; i++) {
switch ((days + i - 1) % 7) {
case 0 :
red();
printf("%3d ", i);
break; // 일요일은 빨간색으로
case 6 :
blue();
printf("%3d\n", i);
break; // 토요일에 줄바꿈
default :
white();
printf("%3d ", i);
break; // 평일
}
}
// 전월에 출력된 부분 삭제
for (white(); i <= 50; i++) {
switch ((days + i - 1) % 7) {
case 6 :
blue();
printf(" \n");
break; // 토요일에 줄바꿈
default :
white();
printf(" ");
break; // 평일
}
}
printf("\n");
}
int main() {
int year = DEFAULT_YEAR;
int month = DEFAULT_MONTH;
char inp;
do {
gotoxy(1, 1);
printCalendar(year, month);
inp = getch();
if (inp == 0 || inp == -32) { // 특수문자 시작 코드
inp = getch();
switch (inp) {
case UP : // 전년도
if (year - 1 > 1) year -= 1;
break;
case DOWN : // 다음 연도
year += 1;
break;
case LEFT : // 전월
if (month - 1 > 0)
month -= 1;
else {
month = 12;
if (year - 1 > 1)
year -= 1;
}
break;
case RIGHT : // 다음 월
if (month + 1 < 13)
month += 1;
else
month = 1, year += 1;
break;
}
}
white();
} while (inp != ESC);
}