C计算日期之间的差异

时间:2017-05-16 19:34:05

标签: c

我一直在搜索如何使用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

2 个答案:

答案 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