C中mktime的不一致结果

MrD*_*MrD 1 c

在各种数值实验中,我看到第一次调用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.

MrD*_*MrD 5

和往常一样,我在总结 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