我现在正在使用gcc编译器在我的RedHat Linux机器上编写一个C程序,它将接受两个日期作为输入并计算它们之间的差异。
但是,我发现了mktime()
的奇怪行为,如下面的代码段所示。
struct tm t;
t.tm_year=4;
t.tm_mon=9;
t.tm_mday=30;
t.tm_hour=0;
t.tm_min=0;
t.tm_sec=0;
printf("%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon, t.tm_day, t.tm_hour, t.tm_min, t.tm_sec);
//result: 4-9-30 0:0:0, which means 1904 Oct 30 00:00:00
mktime(&t);
printf("%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon, t.tm_day, t.tm_hour, t.tm_min, t.tm_sec);
//result: 4-9-29 23:36:36, which means 1904 Oct 29 23:36:36
正如您所看到的,struct tm
在mktime()
之后被转移,这看似不合理。
我做了很多测试,我发现这种奇怪的行为只发生在1904年10月30日00:00:00 - 00:23:24之间的日期分配。
此外,我在我的unix服务器(HP-UX)中测试了相同的代码,它运行完美,没有任何转移。
我想知道以前是否有人有过类似的经历,如果有人能给我一些关于发生了什么的提示?
我在香港时区跑步。
答案 0 :(得分:6)
mktime()
函数假定输入表示本地时间。在不同时间,不同地点的当地时间发生了许多奇怪的变化。
了解您的时区是有帮助的。如果您将时区设置为UTC,我怀疑问题会消失。
我自己没有看到这个问题(我在太平洋夏令时,UTC以西7小时)。
这与卢森堡同年6月的时间变化类似,记录here,当地时钟向前移动了35分24秒。 1904年10月30日是一个星期天,这可能是这种转变的时候。
另见this question关于1927年上海的时间变化(恰好有Jon Skeet得分最高的答案)。
更新:感谢Frxstrem的评论,找到了它。 1904年10月30日,从LMT到HKT,香港的时间发生了变化。如果(a)您的时区设置为香港时间,并且(b)您的系统的时区库足够详细以反映此特定更改,我预计会出现症状。
http://www.timeanddate.com/time/change/hong-kong/hong-kong?year=1904
以下是您的程序的修改版本,可以更清楚地显示问题:
#include <time.h>
#include <stdio.h>
int main(void) {
struct tm t = {
.tm_year = 4,
.tm_mon = 9,
.tm_mday = 30,
.tm_hour = 0,
.tm_min = 0,
.tm_sec = 0,
.tm_isdst = -1, /* let mktime() figure it out */
};
printf("%04d-%02d-%02d %02d:%02d:%02d\n",
1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
// output: 1904-10-30 00:00:00
mktime(&t);
printf("%04d-%02d-%02d %02d:%02d:%02d\n",
1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
// output: 1904-10-29 23:36:42
}
它为tm_isdst
成员分配一个值,而你的成员不会这样做;如果未初始化值,则可能会出现不可预测的行为。此外,您的计划拼错了tm_mday
tm_day
。
这是我系统上的输出:
$ ./c
1904-10-30 00:00:00
1904-10-30 00:00:00
$ TZ=Asia/Hong_Kong ./c
1904-10-30 00:00:00
1904-10-29 23:36:42
$
关于我如何能够相当快地解决这个问题的一些背景知识(这可能对其他人看到类似症状有帮助):
这个问题强烈提醒我this one,我之所以熟悉,只是因为Stack Overflow上的highest-scoring answer有highest-scoring user。那是纯粹的运气。
由于我最初不知道时区,谷歌搜索“1904年时间变化”出现this page讨论卢森堡同年的类似时间变化。世界其他地方在同一时间也做了类似的变化,这可能是向现代标准时区过渡的一部分。
Frxstrem的评论指出:谷歌搜索“1904年香港时间变化”发现this page。