C program days between two dates

前端 未结 6 445
悲&欢浪女
悲&欢浪女 2021-01-02 18:30

I have written a program that should find the days between two dates, but it has some hiccups. The logic makes perfect sense in my head when I read through it, so

6条回答
  •  感动是毒
    2021-01-02 18:46

    First, that leap function feels overly complicated; you don't need to do both dates in one function call, and I'm sure that can be written more succinctly so that it is more obviously correct. Here's a version I've got laying around that isn't succinct but I'm confident it is easy to check the logic:

    int is_leap_year(int year) {
            if (year % 400 == 0) {
                    return 1;
            } else if (year % 100 == 0) {
                    return 0;
            } else if (year % 4 == 0) {
                    return 1;
            } else {
                    return 0;
            }
    }
    

    You could call it like this:

    int year1, year2, leap1, leap2;
    year1 = get_input();
    year2 = get_input();
    leap1 = is_leap_year(year1);
    leap2 = is_leap_year(year2);
    

    No pointers and significantly less code duplication. Yes, I know that is_leap_year() can be reduced to a single if(...) statement, but this is easy for me to read.

    Second, I think you're got a mismatch between 0-indexed arrays and 1-indexed human months:

                if(*month1 < 1 || *month1 > 12)
    

    vs

        int daysPerMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    

    Third, I think that days per month can be calculated slightly nicer:

    int days_in_month(int month, int year) {
            int leap = is_leap_year(year);
            /*               J   F   M   A   M   J   J   A   S   O   N   D */
            int days[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                               {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
            if (month < 0 || month > 11 || year < 1753)
                    return -1;
    
            return days[leap][month];
    }
    

    Here, I assume January is 0; you would need to force the rest of the code to match. (I learned this double-array trick from The Elements of Programming Style (page 54).) The best part of using a routine like this is that it removes the leap condition from the difference calculation.

    Fourth, you're indexing arrays outside their bounds:

                for(i = month1 + 1; i <= 12; i++)
                {
                    if(leap1 == 1)
                        total += daysPerMonthLeap[i];
    

    This is just another instance of the problem with 0-indexed arrays and 1-indexed months -- but be sure that you fix this, too, when you fix the months.

    I have a fear that I haven't yet found all the issues -- you may find it easier to sort the first and the second date after input and remove all that validation code -- and then use names before and after or something to give names that are easier to think through in the complicated core of the calculation.

提交回复
热议问题