정수 형태의 연도(year), 월(month), 일(day)이 주어졌을 때, 해당 날짜가 실제로 존재할 수 있는 날짜인지 판별하는 프로그램을 C 언어로 작성해 보겠습니다.
여기서 유효한 날짜의 범위는 1800년 1월 1일부터 9999년 12월 31일까지이며, 이 범위를 벗어나는 날짜는 모두 잘못된 날짜로 간주합니다. 단순히 연도 범위만 확인하는 것이 아니라, 달력상의 날짜가 갖추어야 할 모든 제약 조건까지 함께 검사해야 합니다.
유효한 날짜의 조건
날짜가 유효하려면 다음 조건들을 모두 만족해야 합니다.
- 일(day)은 1 이상 31 이하여야 합니다.
- 월(month)은 1 이상 12 이하여야 합니다.
- 연도(year)는 1800 이상 9999 이하여야 합니다.
- 4월, 6월, 9월, 11월은 30일까지만 존재하므로 일이 30을 초과할 수 없습니다.
- 2월의 경우 윤년 여부에 따라 다르게 검사합니다.
- 윤년이라면 일은 29일을 초과할 수 없습니다.
- 평년이라면 일은 28일을 초과할 수 없습니다.
모든 조건을 통과하면 유효한 날짜이고, 하나라도 어긋나면 유효하지 않은 날짜입니다.
윤년 판별 규칙
2월의 일수를 정확히 검사하려면 윤년 판별이 필수적입니다. 윤년의 조건은 다음과 같습니다.
- 연도가 4로 나누어 떨어지고, 100으로 나누어 떨어지지 않으면 윤년입니다.
- 단, 400으로 나누어 떨어지는 연도는 예외적으로 윤년입니다.
예제
입력: y = 2002, d = 29, m = 11
출력: 유효한 날짜입니다
입력: y = 2001, d = 29, m = 2
출력: 유효하지 않은 날짜입니다
첫 번째 예제는 11월 29일로 실제 존재하는 날짜이므로 유효합니다. 반면 두 번째 예제는 2001년이 평년이므로 2월 29일은 존재할 수 없는 날짜입니다.
알고리즘
시작
함수 int isleap(int y)
단계 1 -> (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0) 이면,
1을 반환
단계 2 -> 그렇지 않으면,
0을 반환
함수 int datevalid(int d, int m, int y)
단계 1 -> y < min_yr 또는 y > max_yr 이면,
0을 반환
단계 2 -> m < 1 또는 m > 12 이면,
0을 반환
단계 3 -> d < 1 또는 d > 31 이면,
0을 반환
단계 4 -> m == 2 이면,
윤년이면 d <= 29 인지,
평년이면 d <= 28 인지 검사하여 결과 반환
단계 5 -> m이 4, 6, 9, 11 중 하나이면,
d <= 30 인지 검사하여 결과 반환
모든 검사를 통과하면 1을 반환
main 함수
단계 1 -> y = 2002, d = 29, m = 11 로 초기화
단계 2 -> datevalid(d, m, y) 가 참이면,
"Date is valid" 출력
단계 3 -> 그렇지 않으면,
"Date is not valid" 출력
종료
C 언어 구현
#include <stdio.h>
#define max_yr 9999
#define min_yr 1800
// 윤년 여부를 확인하는 함수 (윤년이면 1 반환)
int isleap(int y) {
if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
return 1;
else
return 0;
}
// 날짜의 유효성을 검사하는 함수
int datevalid(int d, int m, int y) {
if (y < min_yr || y > max_yr)
return 0;
if (m < 1 || m > 12)
return 0;
if (d < 1 || d > 31)
return 0;
// 월에 따라 일수를 세밀하게 검사
if (m == 2) {
if (isleap(y))
return (d <= 29); // 윤년 2월은 최대 29일
else
return (d <= 28); // 평년 2월은 최대 28일
}
// 4월, 6월, 9월, 11월은 30일까지
if (m == 4 || m == 6 || m == 9 || m == 11)
return (d <= 30);
return 1;
}
int main(void) {
int y = 2002;
int d = 29;
int m = 11;
if (datevalid(d, m, y))
printf("Date is valid\n");
else
printf("Date is not valid\n");
return 0;
}
실행 결과
위 코드를 컴파일하여 실행하면 다음과 같은 결과가 출력됩니다.
Date is valid
2002년 11월 29일은 실제로 존재하는 날짜이므로 "Date is valid"가 출력됩니다. 만약 y = 2001, d = 29, m = 2 로 값을 바꾸어 실행하면, 2001년은 평년이기 때문에 "Date is not valid"가 출력되는 것을 확인할 수 있습니다.