计算指定日期距离下次生日的时间

问题描述

题目:编写一个程序,计算今天到下次生日中间隔多少天。

日期通过一个一维数组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 

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

你可能感兴趣的:(算法,c++,开发语言)