【发布时间】:2014-08-19 02:36:27
【问题描述】:
我们知道时区 UTC+8 有一些时钟变化。例如,在 1928 年 1 月 1 日 00:00:00,时钟倒转 0:05:52 到 1927 年 12 月 31 日 23:54:08。
此外,在 1940-1941 年和 1986-1991 年使用夏令时。当我在 linux 下使用这些日期测试函数 mktime 时,我有不同的返回值。代码如下:
#include <stdio.h>
#include <string.h>
#include <time.h>
int main(int argc, char *argv[])
{
struct tm timeinfo;
memset(&timeinfo, 0, sizeof(timeinfo));
while(fscanf(stdin, "%d%d%d%d%d%d",
&timeinfo.tm_year, &timeinfo.tm_mon, &timeinfo.tm_mday,
&timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec) != EOF)
{
timeinfo.tm_year -= 1900;
timeinfo.tm_mon -= 1;
fprintf(stdout, "%lld\n", mktime(&timeinfo));
}
return 0;
}
以测试输入输出为例,同样的输入“1940 6 2 23 59 59”和“1940 6 3 1 0 0”会根据调用顺序不同返回值不同:
1940 6 2 23 59 59
-933494401
1940 6 3 1 0 0
-933490800
1940 6 3 1 0 0
-933494400
1940 6 2 23 59 59
-933498001
1940 6 2 23 59 59
-933494401
相同的输入 1940 6 3 1 0 0
这是为什么呢?为什么mktime的返回值根据调用顺序不同?
我已经阅读了mktime 的某些版本的源代码,但没有找到任何可能导致此问题的代码部分。
谁能解释为什么会这样?非常感谢。
新增案例:
1927 12 31 23 54 8
-1325491552
1927 12 31 23 54 7
-1325491905
1927 12 31 23 54 8
-1325491904
1928 1 1 0 0 0
-1325491200
1927 12 31 23 54 8
-1325491552
【问题讨论】:
-
建议:最好使用
while(fscanf(stdin, "%d%d%d%d%d%d", ...) == 6) -
在调用
mktime(&timeinfo)之前,使用timeinfo.tm_isdst = -1(DST不可用)来避免继承之前的值。只有tm_wday和tm_yday可以保持未初始化状态。 -
尝试
"%lld\n"-->"%ld\n"并检查是time_t类型long long int? -
@BLUEPIXY 是正确的,考虑
fprintf(stdout, "%lld\n", (long long) mktime(&timeinfo));以消除潜在的printf()问题。 -
"为什么mktime的返回值不同,取决于调用顺序?"因为需要的7个字段中只有6个被初始化。
标签: c++ c timezone glibc mktime