求时间之差(结构体)
-
标签
-
时间限制
1000MS
-
内存限制
128MB
-
IO 类型
Standard IO
-
出题人
root
-
难度
高
描述
定义两个结构体TDate和TTime分别用来表示日期和时间,TDate包含年、月、日,TTime包含时、分、秒。从键盘输入两个时间点,计算这两个时间点之间的时间间隔。时间点的输入格式为:yy/mm/dd hh:mm:ss
输入
两个时间点,格式为yy/mm/dd hh:mm:ss
输出
两个时间点之差。
输入样例 1 点击复制
2012/12/11 18:00:00 2012/12/12 19:01:01
输出样例 1
-0000/00/01 01:01:01
提示
注意闰年
#include <stdio.h>
#include <math.h>
struct TDate {
int yy;
int mm;
int dd;
};
struct TTime {
int hh;
int mm;
int ss;
};
int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int c1 = 0, c2 = 0, c3 = 0;
// 判断是否是闰年
int isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int flag = 1; //是否需要输出负号
// 计算两个日期之间的天数差
void dateDiff(struct TDate d1, struct TDate d2) {
if (d1.yy > d2.yy || (d1.yy == d2.yy && d1.mm > d2.mm) || (d1.yy == d2.yy && d1.mm == d2.mm && d1.dd > d2.dd)) {//1比2大的情况,交换d1,d2,使d1始终最小
struct TDate temp = d1;
d1 = d2;
d2 = temp;
flag = 0;
}
int bc = d1.dd;//存储d1原始的dd
while (d1.yy < d2.yy || (d1.yy == d2.yy && d1.mm < d2.mm)) {
d1.dd++;
if (d1.dd > daysInMonth[d1.mm - 1] + (d1.mm == 2 && isLeapYear(d1.yy))) {//超出一个月,dd重新变为0,如果是闰年,二月则额外加一天
d1.dd = 1;
c2 += 1;
d1.mm++;
if (d1.mm > 12) {//超过一年
d1.mm = 1;
c1 += 1;
d1.yy++;
}
}
}
if (bc > d2.dd) {
c2 -= 1;
d1.mm -= 1;
}
d1.dd = bc;
while (d1.dd != d2.dd) {
c3++;
d1.dd = d1.dd + 1;
if (d1.dd > daysInMonth[d1.mm - 1] + (d1.mm == 2 && isLeapYear(d1.yy)))
d1.dd = 1;
}
return;
}
// 计算两个时间之间的秒数差
int timeDiff(struct TTime t1, struct TTime t2) {
return (t1.hh - t2.hh) * 3600 + (t1.mm - t2.mm) * 60 + (t1.ss - t2.ss);
}
int main() {
struct TDate d1;
struct TDate d2;
struct TTime t1;
struct TTime t2;
scanf("%d/%d/%d%d:%d:%d", &d1.yy, &d1.mm, &d1.dd, &t1.hh, &t1.mm, &t1.ss);
scanf("%d/%d/%d%d:%d:%d", &d2.yy, &d2.mm, &d2.dd, &t2.hh, &t2.mm, &t2.ss);
dateDiff(d1, d2);
if (flag == 1) {//要输出负号,交换t1,t2
printf("-");
struct TTime temp = t1;
t1 = t2;
t2 = temp;
}
int seconds = timeDiff(t1, t2);
if (seconds < 0) {//不足一天
seconds += 24 * 60 * 60;
c3 -= 1;
}
printf("%04d/%02d/%02d %02d:%02d:%02d\n", c1, c2, c3, abs(seconds / 3600), abs(seconds % 3600 / 60), abs(seconds % 60));
}
这一段的思路如下:
-
首先,它初始化一个名为
days
的变量,用于存储两个日期之间的天数差。 -
然后,它进入一个
while
循环,只要d1
(第一个日期)早于d2
(第二个日期),循环就会继续。 -
在循环中,首先将
d1
的日期(天)增加 1。 -
然后,它检查增加后的
d1
的日期(天)是否超过了该月的天数。如果是,那么它将d1
的日期(天)重置为 1,并将d1
的月份增加 1。这里需要注意的是,如果d1
的月份是2月(即二月),并且d1
的年份是闰年,那么二月的天数应该是29天,而不是28天。这是通过调用isLeapYear(d1.year)
函数并将结果加到daysInMonth[d1.month - 1]
上来实现的。 -
接下来,它检查增加后的
d1
的月份是否超过了12。如果是,那么它将d1
的月份重置为 1,并将d1
的年份增加 1。 -
在每次循环的最后,它将
days
的值增加 1,表示d1
和d2
之间的天数差增加了一天。 -
当
d1
不再早于d2
时,while
循环结束,函数返回days
,即d1
和d2
之间的天数差。
这个函数的基本思想是,通过逐日增加 d1
的日期(天),并同时更新月份和年份(如果需要的话),直到 d1
不再早于 d2
,从而计算出两个日期之间的天数差。