分类 C/C++ 下的文章

#include <stdio.h>
#include <stdlib.h>

//日期结构体
typedef struct Date
{
    int year;
    int month;
    int day;
}Date;

/**
 * 主函数
 */
int main()
{
    //声明开始日期与结束日期变量
    Date start, stop;

    //声明结果变量
    int day;

    //再次计算
    replay:
    
    //清空数据
    day = 0;
    start.year = 0; start.month = 0; start.day = 0;
    stop.year = 0; stop.month = 0; stop.day = 0;

    //输入开始日期,保存至结构体变量
    printf("请输入开始日期(格式为:2002-10-29):");
    scanf("%d-%d-%d", &start.year, &start.month, &start.day);

    //验证日期是否正确
    if(start.month < 1 || start.month > 12){
        printf("输入月份范围有误。\n");
        system("pause");
        goto replay;
    }
    if(start.day < 1){
        printf("输入日期范围有误。\n");
        system("pause");
        goto replay;
    }
    if(start.month == 2){
        if(isLeapYear(start.year)){
            if(start.day > 29){
                printf("%d年为闰年,2月日期不可大于29日。\n", start.year);
                system("pause");
                goto replay;
            }
        }else{
            if(start.day > 28){
                printf("%d年非闰年,2月日期不可大于28日。\n", start.year);
                system("pause");
                goto replay;
            }
        }
    }else{
        if(start.day > getMonthDay(start.month)){
            printf("输入日期有误,%d年%d月仅有%d天。\n", start.year, start.month, getMonthDay(start.month));
            system("pause");
            goto replay;
        }
    }

    //输入结束日期,保存至结构体变量
    printf("请输入结束日期(格式为:2002-10-29):");
    scanf("%d-%d-%d", &stop.year, &stop.month, &stop.day);

    //验证日期是否正确
    if(stop.month < 1 || stop.month > 12){
        printf("输入月份有误。\n");
        system("pause");
        goto replay;
    }
    if(stop.day < 1){
        printf("输入日期有误。\n");
        system("pause");
        goto replay;
    }
    if(stop.month == 2){
        if(isLeapYear(stop.year)){
            if(stop.day > 29){
                printf("%d年为闰年,2月日期不可大于29日。\n", stop.year);
                system("pause");
                goto replay;
            }
        }else{
            if(stop.day > 28){
                printf("%d年非闰年,2月日期不可大于28日。\n", stop.year);
                system("pause");
                goto replay;
            }
        }
    }else{
        if(stop.day > getMonthDay(stop.month)){
            printf("输入日期有误,%d年%d月仅有%d天。\n", stop.year, stop.month, getMonthDay(stop.month));
            system("pause");
            goto replay;
        }
    }
    
    //检查日期并分别处理
    if(start.year > stop.year){
        //开始年大于结束年,调用计算函数
        day = dateDiff(stop, start);
    }else if(start.year == stop.year){
        //开始年与结束年相等,进一步判断月份
        if(start.month > stop.month){
            //开始月大于结束月,调用计算函数
            day = dateDiff(stop, start);
        }else if(start.month == stop.month){
            //开始月等于结束月,直接计算差额
            if(start.day < stop.day){
                //开始日小于结束日,更换参数顺序计算
                day = stop.day - start.day;
            }else{
                //直接计算结果
                day = start.day - stop.day;
            }
        }else{
            //开始月小于结束月,更换参数顺序计算调用计算函数
            day = dateDiff(start, stop);
        }
    }else{
        //开始年小于结束年,更换参数顺序计算调用计算函数
        day = dateDiff(start, stop);
    }

    //输出计算结果
    printf("输入日期差额为:%d天\n", day);

    //输出按任意键继续,以便查看结果
    system("pause");

    //跳回开头再次计算
    goto replay;

    //返回结果(不会被执行)
    return day;
}

/**
 * 日期差计算
 */
int dateDiff(Date start, Date stop)
{
    //声明结果变量
    int diffDay = 0;
    
    //兼容C89标准,在for以外声明变量
    int y,m; 

    //加入尾年尾月天数
    diffDay = stop.day;

    //加入首年首月天数
    if(isLeapYear(start.year) && start.month == 2){
        //首年为闰年且首月为2月进一步判断
        if(start.day < 29){
            diffDay = 29 - start.day + diffDay;
        }
    }else{
        //首年非闰年正常计算
        diffDay = getMonthDay(start.month) - start.day + diffDay;
    }

    if(start.year == stop.year){
        //一年内日期差计算

        //如果开始与结束月份非相邻月,循环加入中间月份天数
        if((stop.month - start.month) > 1){
            for(m = start.month + 1; m < stop.month; m = m+1){
                diffDay = diffDay + getMonthDay(m);
            }
            //闰年且开始月到结束月之间(不含本身)存在2月时差值加1
            if(isLeapYear(start.year) && start.month == 1 && stop.month > 2){
                diffDay = diffDay + 1;
            }
        }

        return diffDay;
    }else{
        //多年日期差计算

        //考虑不同年份但为相邻月份的特殊情况
        if(start.year - stop.year == 1 && start.month == 12 && stop.month == 1){
            return diffDay;
        }else{
            //累计添加每年每月的天数
            for(y = start.year; y <= stop.year; y = y+1){
                //计算中间月份天数
                if(y == start.year){
                    //多年计算中的首年,不计算首年首月,所以循环初始值+1
                    for(m = start.month + 1; m <= 12; m = m+1){
                        diffDay = diffDay + getMonthDay(m);
                    }
                    //闰年且开始月为1月的差值加1
                    if(isLeapYear(y) && start.month == 1){
                        diffDay = diffDay + 1;
                    }
                }else if(y == stop.year){
                    //多年计算的尾年,不计算尾年尾月,所以结束条件不加等于
                    for(m = 1; m < stop.month; m = m+1){
                        diffDay = diffDay + getMonthDay(m);
                    }
                    //闰年且结束月为2月以后的差值加1
                    if(isLeapYear(y) && stop.month > 2){
                        diffDay = diffDay + 1;
                    }
                }else{
                    //中间年,1-12月全计
                    for(m = 1; m <= 12; m = m+1){
                        diffDay = diffDay + getMonthDay(m);
                    }
                    //闰年差值额外加1
                    if(isLeapYear(y)){
                        diffDay = diffDay + 1;
                    }
                }
            }
            return diffDay;
        }
    }
}

/**
 * 判断是否闰年
 */
int isLeapYear(int year)
{
    if(year%400 == 0){
        return 1;
    }else{
        if(year%4 == 0 && year%100 != 0){
            return 1;
        }else{
            return 0;
        }
    }
}

/**
 * 获取月份天数
 */
int getMonthDay(int month)
{
    if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12){
        return 31;
    }else if(month == 4 || month == 6 || month == 9 || month == 11){
        return 30;
    }else if(month == 2){
        //闰年多的一天在循环中判断添加,在此不做判断
        return 28;
    }else{
        return -1;
    }
}