[英]How to calculate the number of days between two given dates? (Leap year obstacle)
[英]calculate how many leap days between two dates
我已经写下了这段代码,该程序的目的是计算两个给定日期和时间之间的分钟数。 让我们说一下之间的分钟差:
14/1/2016 23:18
and
14/1/2004 23:18
is:
6,311,520.00 minutes
这是我写的代码:
我在计算中有一些错误,从我发现我的问题到与正确答案最多相差1440分钟-由excel检查。 我认为我的问题是在两个日期之间的L日的计算中:
#include <stdio.h>
typedef struct {
int year;
int month;
int day;
int hour;
int minute;
int second;
}time;
time time1,time2;
long calcTime(time,time);
int calcDaysFromStart(int,int);
int leapcheck(int);
int main()
{
printf("Hello\n");
printf("For calculating the difference between two times:\n");
printf("Enter the date for first time:\n");
printf("Enter day:\n");
scanf("%d",&time1.day);
printf("Enter month:\n");
scanf("%d",&time1.month);
printf("Enter year:\n");
scanf("%d",&time1.year);
printf("Enter the exact hour for first time:\n");
printf("Enter the hour:\n");
scanf("%d",&time1.hour);
printf("Enter the minutes:\n");
scanf("%d",&time1.minute);
printf("Enter the seconds:\n");
scanf("%d",&time1.second);
printf("-----------------------------------\n");
printf("Enter the date for second time:\n");
printf("Enter day:\n");
scanf("%d",&time2.day);
printf("Enter month:\n");
scanf("%d",&time2.month);
printf("Enter year:\n");
scanf("%d",&time2.year);
printf("Enter the exact hour for first time:\n");
printf("Enter the hour:\n");
scanf("%d",&time2.hour);
printf("Enter the minutes:\n");
scanf("%d",&time2.minute);
printf("Enter the seconds:\n");
scanf("%d",&time2.second);
printf("-----------------------------------\n");
printf("-----------------------------------\n");
printf("The first time is: %d:%d:%d %d/%d/%d\n", time1.hour ,time1.minute ,time1.second ,time1.day, time1.month ,time1.year);
printf("The second time is: %d:%d:%d %d/%d/%d\n", time2.hour ,time2.minute ,time2.second ,time2.day, time2.month ,time2.year);
printf("The Difference between the two times in minutes is:%ld\n", calcTime(time1,time2));
return 1;
}
long calcTime(time time1,time time2)
{
long t1,t2,totalDiff;
long yearDiffeInMinutes = 0;
int leapt1, leapt2,leapAdd;
leapt1 = leapcheck(time1.year);
leapt2 = leapcheck(time2.year);
int daysFromStartt1, daysFromStartt2;
daysFromStartt1 = calcDaysFromStart(time1.month,leapt1);
daysFromStartt2 = calcDaysFromStart(time2.month,leapt2);
t1 = time1.minute+time1.hour*60+time1.day*1440+daysFromStartt1*1440;
t2 = time2.minute+time2.hour*60+time2.day*1440+daysFromStartt2*1440;
if (time1.year>time2.year)
{
leapAdd = (time1.year-time2.year)/4;
if ((leapt1==1) && (time1.month<3))
leapAdd--;
if((leapt2==1) && (time2.month>2))
leapAdd--;
printf("THE PARAM leapApp IS:%d\n",leapAdd);
yearDiffeInMinutes = ((time1.year-time2.year)*525600+leapAdd*1440);
totalDiff = yearDiffeInMinutes+(t1-t2);
printf("The first time is bigger\n");
return totalDiff;
}
else if(time2.year>time1.year)
{
leapAdd = (time2.year-time1.year)/4;
if ((leapt2==1) && (time2.month<3))
leapAdd--;
if((leapt1==1) && (time1.month>2))
leapAdd--;
yearDiffeInMinutes = ((time2.year-time1.year)*525600+leapAdd*1440);
totalDiff = yearDiffeInMinutes+(t2-t1);
printf("The second time is bigger\n");
return totalDiff;
}
else if(t1>t2)/**both times are in the same year**/
{
printf("The first time is bigger\n");
if ((leapt1==1) && (time1.month>2))
if(time2.month<2)
return (t1-t2+1440);
return(t1-t2);
}
else if(t2>t1)
{
printf("The second time is bigger\n");
if ((leapt2==1) && (time2.month>2))
if(time1.month<2)
return (t2-t1+1440);
return (t2-t1);
}
else
{
printf("Both times are equals\n");
return 0;
}
}
/**check if the year is leap, return 0 if not a leap and 1 if a leap**/
int leapcheck(int year)
{
if(year%400==0 || (year%100!=0 && year%4==0))
{
printf("THE YEAR %d IS LEAP\n",year);
return 1;
}
printf("THE YEAR %d is NOT LEAP\n",year);
return 0;
}
/**clalculate how many days past from start ofthe year**/
int calcDaysFromStart(int month, int leap)
{
if (month==1)
return 0;
else if (month==2)
return 31;
else if (month==3)
return (59+leap);
else if (month==4)
return (90+leap);
else if (month==5)
return (120+leap);
else if (month==6)
return (151+leap);
else if (month==7)
return (181+leap);
else if (month==8)
return (212+leap);
else if (month==9)
return (243+leap);
else if (month==10)
return (273+leap);
else if (month==11)
return (304+leap);
else if (month==12)
return (334+leap);
else return -1;
}
计算
leapAdd = (time1.year-time2.year)/4;
是错的。 2003年至2005年之间是a年,但这将被忽略。 同样,跨度13年可以包括三到四个four年,而不会影响世纪复杂性。
正确的代码是
leapAdd = time1.year/4 - time2.year/4 // how many Caesarian leap years
- time1.year/100 + time2.year/100 // Centuries
+ time1.year/400 - time2.year/400; // last correction.
(如果time2.year > time1.year
则具有互换的角色)。
也,
t1 = time1.minute+time1.hour*60+time1.day*1440+daysFromStartt1*1440;
盘算。 在本月的第一天,没有要添加的整天,因此应该
(time1.day-1)*1440
同样,分钟也同样(time1.hour-1)*60
。 由于超量是恒定的,因此这不会影响时间差的计算。
有一个标准的库函数可以做到这一点。
time_t seconds_begin, seconds_end;
struct tm breakdown;
breakdown.tm_year = 2004 - 1900;
breakdown.tm_mon = 0; /* january */
breakdown.tm_mday = 14;
breakdown.tm_hour = 23;
breakdown.tm_min = 18;
seconds_begin = mktime( & breakdown );
breakdown.tm_year = 2016 - 1900;
seconds_end = mktime( & breakdown );
printf( "%.2f minutes", (seconds_end - seconds_begin) / 60. );
6311520.00分钟
在Unix系统上,我认为它比Excel更可靠。
您的示例的快速解决方案是在if
和else
中都添加以下行:
if(leapt1==1 && leapt2==1)
leapAdd++;
但是此代码将在更大的间隔内失败(其中包括100年和400年的跨越式异常)。 因此,我建议您重写这部分代码; 例如,您可以在间隔的每一年中进行迭代,并检查间隔是跳跃的还是普通的(使用特殊的大小写来表示间隔的开始和结束)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.