2 つの日付の間の日数を検出するプログラムを作成しましたが、問題がいくつかあります。私がそれを読んだとき、ロジックは私の頭の中で完全に理にかなっています。
まず、異なる年の 2 つの日付を入力すると、出力は常に約 1 か月ずれます (ほとんどの場合は 31 ですが、1 つの場合は 32 です...数字を見てください)。次に、ちょうど 1 か月離れた 2 つの日付は、2 番目の月の日数を返します (つまり、1/1/1 から 2/1/1 は 28 になります)。このプログラムには不可避的に他にも奇妙なことがいくつかありますが、私が何を間違っているのかを理解するのに十分な情報であることを願っています. 私の人生では、これを自分で理解することはできません。私はCに比較的慣れていないので、優しくしてください=)
ありがとう
// Calculates the number of calendar days between any two dates in history (beginning with 1/1/1).
#include <stdio.h>
#include <stdlib.h>
void leap(int year1, int year2, int *leap1, int *leap2);
void date(int *month1, int *day1, int *year1, int *month2, int *day2, int *year2, int *leap1, int *leap2);
int main(void)
{
int month1, day1, year1, month2, day2, year2, leap1, leap2;
int daysPerMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int daysPerMonthLeap[] = {31,29,31,30,31,30,31,31,30,31,30,31};
leap(year1, year2, &leap1, &leap2);
date(&month1, &day1, &year1, &month2, &day2, &year2, &leap1, &leap2);
if(year1 == year2)
{
int i, total;
if(month1 == month2) // Total days if month1 == month2
{
total = day2 - day1;
printf("There are %d days between the two dates.", total);
}
else
{
if(leap1 == 1)
total = daysPerMonthLeap[month1] - day1;
else
total = daysPerMonth[month1] - day1;
for(i = month1 + 1; i < month2; i++) // Days remaining between dates (excluding last month)
{
if(leap1 == 1)
total += daysPerMonthLeap[i];
else
total += daysPerMonth[i];
}
total += day2; // Final sum of days between dates (including last month)
printf("There are %d days between the two dates.", total);
}
}
else // If year1 != year2 ...
{
int i, total, century1 = ((year1 / 100) + 1) * 100, falseleap = 0;
if(leap1 == 1)
total = daysPerMonthLeap[month1] - day1;
else
total = daysPerMonth[month1] - day1;
for(i = month1 + 1; i <= 12; i++) // Day remaining in first year
{
if(leap1 == 1)
total += daysPerMonthLeap[i];
else
total += daysPerMonth[i];
}
for(i = 1; i < month2; i++) // Days remaining in final year (excluding last month)
{
if(leap2 == 1)
total += daysPerMonthLeap[i];
else
total += daysPerMonth[i];
}
int leapcount1 = year1 / 4; // Leap years prior to and including first year
int leapcount2 = year2 / 4; // Leap years prior to and NOT including final year
if(year2 % 4 == 0)
leapcount2 -= 1;
int leaptotal = leapcount2 - leapcount1; // Leap years between dates
for(i = century1; i < year2; i += 100) // "False" leap years (divisible by 100 but not 400)
{
if((i % 400) != 0)
falseleap += 1;
}
total += 365 * (year2 - year1 - 1) + day2 + leaptotal - falseleap; // Final calculation
printf("There are %d days between the two dates.", total);
}
return 0;
}
void leap(int year1, int year2, int *leap1, int *leap2) // Determines if first and final years are leap years
{
if(year1 % 4 == 0)
{
if(year1 % 100 == 0)
{
if(year1 % 400 == 0)
*leap1 = 1;
else
*leap1 = 0;
}
else
*leap1 = 1;
}
else
*leap1 = 0;
if(year2 % 4 == 0)
{
if(year2 % 100 == 0)
{
if(year2 % 400 == 0)
*leap2 = 1;
else
*leap2 = 0;
}
else
*leap2 = 1;
}
else
*leap2 = 0;
}
void date(int *month1, int *day1, int *year1, int *month2, int *day2, int *year2, int *leap1, int *leap2)
{
for(;;) // Infinite loop (exited upon valid input)
{
int fail = 0;
printf("\nEnter first date: ");
scanf("%d/%d/%d", month1, day1, year1);
if(*month1 < 1 || *month1 > 12)
{
printf("Invalid entry for month.\n");
fail += 1;
}
if(*day1 < 1 || *day1 > 31)
{
printf("Invalid entry for day.\n");
fail += 1;
}
if(*year1 < 1)
{
printf("Invalid entry for year.\n");
fail += 1;
}
if(daysPerMonth[month1] == 30 && *day1 > 30)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
if(*month1 == 2)
{
if(*leap1 == 1 && *day1 > 29)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
else if(*day1 > 28)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
}
if(fail > 0)
continue;
else
break;
}
for(;;)
{
int fail = 0;
printf("\nEnter second date: ");
scanf("%d/%d/%d", month2, day2, year2);
if(*year1 == *year2)
{
if(*month1 > *month2)
{
printf("Invalid entry.\n");
fail += 1;
}
if(*month1 == *month2 && *day1 > *day2)
{
printf("Invalid entry.\n");
fail += 1;
}
}
if(*month2 < 1 || *month2 > 12)
{
printf("Invalid entry for month.\n");
fail += 1;
}
if(*day2 < 1 || *day2 > 31)
{
printf("Invalid entry for day.\n");
fail += 1;
}
if(*year2 < 1)
{
printf("Invalid entry for year.\n");
fail += 1;
}
if(daysPerMonth[month2] == 30 && *day2 > 30)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
if(*month2 == 2)
{
if(*leap2 == 1 && *day2 > 29)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
else if(*day2 > 28)
{
printf("Invalid month and day combination.\n");
fail += 1;
}
}
if(fail > 0)
continue;
else
break;
}
}