2014-11-06 69 views
1

我不明白为什么difftime会返回一个奇怪的值,所以这里是数据集和我正在使用的代码。difftime在特定日期返回奇怪的值

代码:

struct tm currentTime; 
currentTime.tm_year = 2014 - 1900; 
currentTime.tm_mon = 9 - 1; 
currentTime.tm_mday = 6; 
currentTime.tm_hour = 23; 
currentTime.tm_min = 59; 
currentTime.tm_sec = 0; 
currentTime.tm_wday = 7 - 1; 

struct tm previousTime; 
previousTime.tm_year = 2014 - 1900; 
previousTime.tm_mon = 9 - 1; 
previousTime.tm_mday = 6; 
previousTime.tm_hour = 23; 
previousTime.tm_min = 58; 
previousTime.tm_sec = 0; 
previousTime.tm_wday = 7 - 1; 

cout << difftime(mktime(&currentTime), mktime(&previousTime)) << endl; 

此打印:

3660 

任何想法,为什么我得到这个值? 我应该得到60,因为有一分钟的差异。 我尝试了一些其他的值,他们都工作.. 我用mingw使用CodeBlocks。

编辑:回答:使用tm_isdst解决了问题!血腥DST:P

struct tm currentTime; 
currentTime.tm_year = 2014 - 1900; 
currentTime.tm_mon = 9 - 1; 
currentTime.tm_mday = 6; 
currentTime.tm_hour = 23; 
currentTime.tm_min = 59; 
currentTime.tm_sec = 0; 
currentTime.tm_wday = 7 - 1; 
currentTime.tm_isdst = - 1; 

struct tm previousTime; 
previousTime.tm_year = 2014 - 1900; 
previousTime.tm_mon = 9 - 1; 
previousTime.tm_mday = 6; 
previousTime.tm_hour = 23; 
previousTime.tm_min = 58; 
previousTime.tm_sec = 0; 
previousTime.tm_wday = 7 - 1; 
previousTime.tm_isdst = - 1; 

cout << difftime(mktime(&currentTime), mktime(&previousTime)) << endl; 
+1

除了这个不编译[因为成员名称不正确](http://en.cppreference.com/w/cpp/chrono/c/tm),一旦你修正了错误[你按预期得到60。](http://coliru.stacked-crooked.com/a/af76e98edee8cdbb)。 TL;博士;不能重现。 – Borgleader 2014-11-06 20:09:22

+0

@Borgleader对不起,我没有很好地复制我的程序。我用新的值更新了它,但我仍然得到一个奇怪的值:3660 – 2014-11-06 20:12:36

+0

因此,您的代码中实际上包含'previousTime.tm_hour = 22;'。 – 2014-11-06 20:16:13

回答

3

在致电mktime(),通常需要设置的struct tm 7场。由于OP仅设置了其中的6个,未初始化的数据在字段tm_isdst中导致3600秒的意外变化。在struct tm currentTime = { 0 };

struct tm currentTime; 
currentTime.tm_year = 2014 - 1900; 
currentTime.tm_mon = 9 - 1; 
currentTime.tm_mday = 6; 
currentTime.tm_hour = 23; 
currentTime.tm_min = 59; 
currentTime.tm_sec = 0; 

currentTime.tm_isdst = -1; // ** 
// currentTime.tm_wday = 7 - 1; 

mktime(&currentTime); 

推荐给零填充struct tm以保证被指定的所有字段为struct tm可以含有除了9个字段:int tm_sec tm_min tm_hour tm_mday tm_mon tm_year tm_wday tm_yday tm_isdst


注:

tm_wdaytm_yday原来的值被忽略,被mktime()重新计算。其他字段的原始值不限于其正常范围,并且也被重新计算。

** tm_isdst的正值或零值会导致mktime函数最初假定夏令时分别对指定时间有效或无效。负值导致它试图确定夏令时是否在指定时间内有效。

+0

这里很好的解释。基本上,在使用变量之前填充变量比较安全? – 2014-11-06 21:18:58

+1

@Hawknight由于'struct tm'至少具有定义良好的9个字段,所以可移植代码不应该冒其他人未初始化的风险。一般来说,当使用不自己制作的结构时,最好在使用前将它们清零。如果你的代码没有被填满,事情就会像预期的那样,除了接近DST转换。如果不深入挖掘,在知道设置时使用'tm_isdst = 0或1',否则使用'-1'。 – chux 2014-11-06 21:26:47