在各种数值实验中,我看到第一次调用mktime会以一种糟糕的方式改变结果。如您所见,循环中的第一个结果如果关闭一小时而其他结果很好。我的错误是什么?
看到这个 MWE:
#define _XOPEN_SOURCE
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
int main()
{
int i;
for(i=0;i<3;i++)
{
// Set timestamp
char timestamp[16] = "Feb 27 00:00:19";
// Get local time
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime (&rawtime);
// Interpret time string
struct tm querytime;
// Expected format: Mmm dd hh:mm:ss
// %b = Abbreviated month name
// %e = Day of the month, space-padded ( 1-31)
// %H = Hour in 24h format (00-23)
// %M = Minute (00-59)
// %S = Second (00-59)
strptime(timestamp, "%b %e %H:%M:%S", &querytime);
// Year is missing in aboves string - add the current year
querytime.tm_year = (*timeinfo).tm_year;
int unixtime = (int)mktime(&querytime);
printf("%i - %s - %s\n",unixtime, timestamp, asctime(&querytime));
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果:
gcc test.c && ./a.out
1488146419 - Feb 27 00:00:19 - Sun Feb 26 23:00:19 2017
1488150019 - Feb 27 00:00:19 - Mon Feb 27 00:00:19 2017
1488150019 - Feb 27 00:00:19 - Mon Feb 27 00:00:19 2017
Run Code Online (Sandbox Code Playgroud)
我的时区是CET.
和往常一样,我在总结 StackOverflow 的所有内容后不久就发现了这个问题。问题是我没有正确初始化struct tm. 如果我将相应的代码行更改为
struct tm querytime = { 0 };
querytime.tm_isdst = -1; // See comment below
Run Code Online (Sandbox Code Playgroud)
那么问题就消失了:
gcc test.c && ./a.out
1488150019 - Feb 27 00:00:19 - Mon Feb 27 00:00:19 2017
1488150019 - Feb 27 00:00:19 - Mon Feb 27 00:00:19 2017
1488150019 - Feb 27 00:00:19 - Mon Feb 27 00:00:19 2017
Run Code Online (Sandbox Code Playgroud)
我将把它留在这里以供将来参考。
请注意,初始化所有数量0会导致夏令时 (DST) 出现问题。根据 ISO/IEC 9899:TC3,tm_isdst, 应初始化为负值,如tm_isdst = 0转换为DST = No而不是预期的DST = Unknown。