2017-05-16 288 views
1

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

嘗試%f而不是%lf。 –

+1

如果目標是計算兩個日期之間的月份,那麼用「手工」完成一個簡單的月份和年份運算的減法不是更簡單嗎?更大的問題是如何根據當天舍入到最近的月份,因爲這不是每月不變的。 「月」不是確切的度量單位。 –

+0

好奇,爲什麼給2 _dates_,代碼是否需要生成_hour_差異而不是_day_差異?是否有DST關注? – chux

回答

5

你正在閱讀的沒有時間組件的字符串,因此這些領域不被strptime設置。

man page

原則上,此功能不會初始化TM,但只存儲指定的 值。這意味着應在調用 之前初始化tm。不同UNIX系統之間的細節有點不同。 glibc 實現不會觸及那些未明確指定爲 的字段,但它會重新計算tm_wday和tm_yday字段,如果 年,月或日元素中的任何一個發生更改。

當你再調用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是有效的,但沒有效果。

+0

感謝您的幫助和解釋。初始化結構確實給了我一致的結果。 – robnix

+0

@robnix很高興能幫到你。如果您覺得它有用,請隨時[接受此答案](http://stackoverflow.com/help/accepted-answer)。 – dbush

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