我一直在搜索如何使用C在两个日期之间获得差异,但我无法解决它。所以我认为我开始很容易理解它并从那里开始。
根据我见过的一些例子构建应该计算两个日期之间的小时数,这是我提出的代码:
#define _XOPEN_SOURCE
#include <time.h>
#include <stdio.h>
int main()
{
char *time1 = "2015-08-10";
char *time2 = "2017-05-16";
struct tm tm1;
struct tm tm2;
time_t t1;
time_t t2;
double hours;
strptime(time1, "%Y-%m-%d", &tm1);
strptime(time2, "%Y-%m-%d", &tm2);
printf("time1: %s\n", time1);
printf("tm1.year: %d\n", tm1.tm_year);
printf("tm1.mon : %d\n", tm1.tm_mon);
printf("tm1.day : %d\n", tm1.tm_mday);
printf("time2: %s\n", time2);
printf("tm2.year: %d\n", tm2.tm_year);
printf("tm2.mon : %d\n", tm2.tm_mon);
printf("tm2.day : %d\n", tm2.tm_mday);
t1 = mktime(&tm1);
t2 = mktime(&tm2);
hours = difftime(t2, t1) / 60 / 60;
printf("diff: %lf\n", hours);
return 0;
}
它编译并运行但是每次执行它都会给我不同的时间?无法理解为什么?
编译:
$ gcc -Wall main.c -o timespan
执行:
$ ./timespan
time1: 2015-08-10
tm1.year: 115
tm1.mon : 7
tm1.day : 10
time2: 2017-05-16
tm2.year: 117
tm2.mon : 4
tm2.day : 16
diff: -1885271229.700556
$ ./timespan
time1: 2015-08-10
tm1.year: 115
tm1.mon : 7
tm1.day : 10
time2: 2017-05-16
tm2.year: 117
tm2.mon : 4
tm2.day : 16
diff: -652404645.977222
答案 0 :(得分:5)
您正在阅读的字符串没有时间组件,因此这些字段不会由strptime
设置。
来自man page:
注释
原则上,此函数不初始化tm但仅存储 指定的值。这意味着tm应该在之前初始化 呼叫。不同UNIX系统之间的细节略有不同。 glibc 实现不会触及那些未明确的字段 指定,但它重新计算tm_wday和tm_yday字段if 任何年,月或日元素都会发生变化。
当您再调用mktime
时,它会读取这些未初始化的字段,并调用undefined behavior。
您需要初始化这些结构:
struct tm tm1 = {0};
struct tm tm2 = {0};
然后你会得到一致的结果:
time1: 2015-08-10
tm1.year: 115
tm1.mon : 7
tm1.day : 10
time2: 2017-05-16
tm2.year: 117
tm2.mon : 4
tm2.day : 16
diff: 15480.000000
此外,要打印double
类型的值,请使用%f
格式说明符。 %lf
有效,但无效。
答案 1 :(得分:0)
感谢所有帮助。我设法解决了最初的问题(差异在几个月内),对于那些感兴趣的人,这就是产品。
#define _XOPEN_SOURCE 800
#include <time.h>
#include <stdio.h>
struct date_stamp {
int yer;
int mon;
int day;
int hrs;
int min;
int sec;
};
int main()
{
char *time1 = "2015-08-10";
char *time2 = "2016-08-10";
struct tm tm1 = {0}; /* tm structs need to be initialized */
struct tm tm2 = {0};
struct date_stamp diff_date;
time_t t1;
time_t t2;
double diff;
/* convert the time strings into tm structs */
strptime(time1, "%Y-%m-%d", &tm1);
strptime(time2, "%Y-%m-%d", &tm2);
/* make the time_t variables*/
t1 = mktime(&tm1);
t2 = mktime(&tm2);
/* calculate the diffrence in seconds */
diff = difftime(t2, t1);
/*
* appearently there goes 2629746 seconds
* in one gregorian month
*/
diff_date.sec = diff;
diff_date.min = diff / 60;
diff_date.hrs = diff / 60 / 60;
diff_date.day = diff / 60 / 60 / 24;
diff_date.mon = diff / 2629746;
diff_date.yer = diff / 60 / 60 / 24 / 365;
printf("start : %s\n", time1);
printf("end : %s\n", time2);
puts( "-------+-----------");
printf("Year : %d\n", diff_date.yer);
printf("Months : %d\n", diff_date.mon);
printf("Days : %d\n", diff_date.day);
printf("Hours : %d\n", diff_date.hrs);
printf("Minutes: %d\n", diff_date.min);
printf("Seconds: %d\n", diff_date.sec);
return 0;
}
不要认为你的计算是坚如磐石的(一年366天?!?)。但我稍后会调整,至少我有一个基础可以构建。
$ gcc -Wall main.c -o timespan
$ ./timespan
start : 2015-08-10
end : 2016-08-10
-------+-----------
Year : 1
Months : 12
Days : 366
Hours : 8784
Minutes: 527040
Seconds: 31622400