C中两个日期之间的差异

时间:2013-09-26 18:20:10

标签: c linux time.h

我试图通过使用以下C代码来区分两个日期。

但代码总是给出差异0.帮我解决我犯错误的地方。

我在linux下使用gcc编译器。

#include <stdio.h>  
#include <time.h>       
int main ()
{
  struct tm start_date;
  struct tm end_date;
  time_t start_time, end_time;
  double seconds;

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10; start_date.tm_mday = 15; start_date.tm_year = 2013;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10; end_date.tm_mday = 20; end_date.tm_year = 2013;

  start_time = mktime(&start_date);
  end_time = mktime(&end_date);

  seconds = difftime(end_time, start_time);

  printf ("%.f seconds difference\n", seconds);

  return 0;
}

编辑: @qchen的回答帮了解了我的问题。还有一个疑问。以下是我的更新。从答案

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10-1; start_date.tm_mday = 18; start_date.tm_year = 2013-1876;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10-1; end_date.tm_mday = 20; end_date.tm_year = 2013-1876;

tm_year是自1900年以来的一年,那么为什么如果我在1876年到2012年之间取代1876年,我会获得正确的产出。

3 个答案:

答案 0 :(得分:3)

问题是tm_year是自1900年以来的一年,所以2013年将是113 http://en.cppreference.com/w/cpp/chrono/c/tm

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10; start_date.tm_mday = 15; start_date.tm_year = 113;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10; end_date.tm_mday = 20; end_date.tm_year = 113;

鉴于2013年,mktime将返回-1,因为无法表示日历时间。你会认为3913年是一个有效的日历时间,其原因与the year 2038 problem有关,正如Joni所指出的那样

答案 1 :(得分:1)

OP没有检查mktime()`result。

正如@Joni所提到的,设置tm_isdst字段。如果您知道DST是如何应用的,请使用01,否则请使用&#39; -1&#39;让操作系统做出决定。

@qchen提到了1900年的偏移,因为你可能想要.tm_year = 2013-1900

我断言,如果是mktime(),则使用(time_t) -1而不进行检查会导致基本问题。使用健壮的代码,应该测试此返回值并且缺少 打开OP代码以获得意外结果。

答案 2 :(得分:0)

除了未正确指定年份外,您还将取消设置tm_isdst字段。 mktime使用此字段来确定日期是否有夏令时有效,或者是否应从时区数据库中查找DST设置。这可以使结果关闭一个小时。添加以下行:

/* lookup if DST or not */
start_date.tm_isdst = -1;
end_date.tm_isdst = -1;