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
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.