问题描述
题目:编写一个程序,计算今天到下次生日中间隔多少天。
日期通过一个一维数组int [3]保存,例如int date[3],其中date [0]保存年份,date [1]保存月份, date [2]保存日。
要求:
1)编写函数int isLeap(int year)根据判断年份是否为闰年;
2)编写函数int daysInMonth(int year,int month),返回某个月包含的天数;
3)编写函数int isLegal(int date[]),判断一日期是否为合法的日期(判断月和日是否合法),如,2010.1.1 合法,2010.1.32不合法;
4)编写日期输入函数void dateInput(int date[]),在函数中输入年,月,日,并判断输入的日期是否合法,如不合法则重新输入;
5) 在main函数中调用日期输入函数,输入当天的日期和生日,计算今天到下次生日中间隔多少天(要考虑闰年),并在输出结果。
原因分析:
题目本身并不复杂,只涉及到日期推算,关键在于理清逻辑,将所有情况都考虑到即可:
1、生日是2月29日
(1)今年是闰年:
① 现在是否为1月→日期加上1月的剩余天数和2月的天数;
② 现在是否为2月→日期加上当前距离2月29日的天数;
③ 现在大于2月→日期先加上当前月份剩余天数,再加上今年除去当前月份的剩余的天数,然后加上下一次闰年之前的天数,最后加上下一次闰年开始到2月29日的天数;
(2)今年不是闰年:
日期先加上当前月份剩余天数,再加上今年除去当前月份的剩余的天数,然后加上下一次闰年之前的天数,最后加上下一次闰年开始到2月29日的天数;
2、生日不是是2月29日
(1)当前月份小于生日月份:
日期先加上当前月份剩余天数,然后加上除去当前月份后距离生日月份之前的天数,最后加上生日月份初到生日的天数;
(2)当前月份等于生日月份:
① 当前日期不大于生日的日期→日期加上当前日期距离生日日期的天数
② 当前日期大于生日的日期→日期先加上当前月份剩余天数,再加上今年除去当前月份的剩余的天数,然后加上次年初到生日月份之前的天数,最后加上次年生日月份初到生日的天数;
(3)当前月份大于生日月份:
日期先加上当前月份剩余天数,再加上今年除去当前月份的剩余的天数,然后加上次年初到生日月份之前的天数,最后加上次年生日月份初到生日的天数;
代码实现:
#include <stdio.h>
int isLeap(int year) {
return !(year % 400) || (!(year % 4) && (year % 100));
}
int daysInMonth(int year, int month) {
switch (month) {
case 2:
if (isLeap(year))
return 29;
else
return 28;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
default:
return 30;
}
}
int isLegal(int date[]) {
switch (date[1]) {
case 2:
if (isLeap(date[0])) {
if (date[2] >= 1 && date[2] <= 29)
return 1;
else
return 0;
}
else {
if (date[2] >= 1 && date[2] <= 28)
return 1;
else
return 0;
}
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (date[2] >= 1 && date[2] <= 31)
return 1;
else
return 0;
case 4:
case 6:
case 9:
case 11:
if (date[2] >= 1 && date[2] <= 30)
return 1;
else
return 0;
}
}
void dateInput(int date[]) {
scanf_s("%d.%d.%d", &date[0], &date[1], &date[2]);
if (!isLegal(date)) {
printf("Invalid input, please re-enter:");
scanf_s("%d.%d.%d", &date[0], &date[1], &date[2]);
}
}
int main(void)
{
int date_now[3];
int date_birth[3];
int i, days = 0;
printf("Please enter the current date:");
dateInput(date_now);
printf("Please enter date of birth:");
dateInput(date_birth);
if (date_birth[1] == 2 && date_birth[2] == 29) { //生日是2月29日
if (isLeap(date_now[0])) { //今年是闰年
if (date_now[1] == 1) //现在是否为1月
days += daysInMonth(date_now[0], date_now[1]) - date_now[2] + date_birth[2]; //1月的剩余天数和2月的天数
else if (date_now[1] == 2) //现在是否为2月
days += date_birth[2] - date_now[2]; //当前距离2月29日的天数
else { //现在大于2月
days += daysInMonth(date_now[0], date_now[1]) - date_now[2];
//当前月份剩余天数
for (i = date_now[1] + 1; i <= 12; i++)
days += daysInMonth(date_now[0], i); //今年除去当前月份的剩余的天数
for (i = date_now[0] + 1; !isLeap(i); i++)
days += 365; //下一次闰年之前的天数
days += 60; //下一次闰年开始到2月29日的天数
}
}
else { //今年不是闰年
days += daysInMonth(date_now[0], date_now[1]) - date_now[2];
//当前月份剩余天数
for (i = date_now[1] + 1; i <= 12; i++)
days += daysInMonth(date_now[0], i); //今年除去当前月份的剩余的天数
for (i = date_now[0] + 1; !isLeap(i); i++)
days += 365; //下一次闰年之前的天数
days += 60; //下一次闰年开始到2月29日的天数
}
}
else if (date_now[1] < date_birth[1]) { //当前月份小于生日月份
days += daysInMonth(date_now[0], date_now[1]) - date_now[2];
//当前月份剩余天数
for (i = date_now[1] + 1; i < date_birth[1]; i++)
days += daysInMonth(date_now[0], i); //除去当前月份后距离生日月份之前的天数
days += date_birth[2]; //生日月份初到生日的天数
}
else if (date_now[1] == date_birth[1]) { //当前月份等于生日月份
if (date_now[2] <= date_birth[2]) //当前日期不大于生日的日期
days += date_birth[2] - date_now[2]; //当前日期距离生日日期的天数
else { //当前日期大于生日的日期
days += daysInMonth(date_now[0], date_now[1]) - date_now[2];
//当前月份剩余天数
for (i = date_now[1] + 1; i <= 12; i++)
days += daysInMonth(date_now[0], i); //今年除去当前月份的剩余的天数
for (i = 1; i < date_birth[1]; i++)
days += daysInMonth(date_now[0] + 1, i); //次年初到生日月份之前的天数
days += date_birth[2]; //次年生日月份初到生日的天数
}
}
else //当前月份大于生日月份
{
days += daysInMonth(date_now[0], date_now[1]) - date_now[2];
//当前月份剩余天数
for (i = date_now[1] + 1; i <= 12; i++)
days += daysInMonth(date_now[0], i); //今年除去当前月份的剩余的天数
for (i = 1; i < date_birth[1]; i++)
days += daysInMonth(date_now[0] + 1, i); //次年初到生日月份之前的天数
days += date_birth[2]; //次年生日月份初到生日的天数
}
printf("There are %d days until the next birthday.", days);
return 0;
}