gpt4 book ai didi

c - mktime() 奇怪地改变了日期

转载 作者:可可西里 更新时间:2023-11-01 11:46:07 27 4
gpt4 key购买 nike

我现在正在使用 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 tmmktime() 之后移动,这看起来不合理。

我做了很多测试,我发现这种奇怪的行为只发生在 1904 年 10 月 30 日 00:00:00 - 00:23:24 之间的日期分配中。

此外,我在我的 unix 服务器 (HP-UX) 上测试了相同的代码,它运行完美,没有任何偏移。

不知道有没有人有过类似的经历,有没有人可以给我提示一下是怎么回事?

我在香港时区运行。

最佳答案

mktime() 函数假定输入代表本地 时间。在不同时间的不同地点,本地时间出现了许多奇怪的变化。

了解您所在的时区会很有帮助。如果您将时区设置为 UTC,我怀疑问题会消失。

我自己没有看到这个问题(我在太平洋夏令时,UTC 以西 7 小时)。

这看起来类似于同年 6 月在卢森堡发生的时移,记录在案 here , 当本地时钟向前移动 35 分 24 秒时。 1904 年 10 月 30 日是星期日,很可能是发生这种转变的时间。

另见 this question关于 1927 年上海的时间变化(恰好有 Jon Skeet 得分最高的答案)。

更新:找到了,感谢 Frxstrem 的评论。 1904 年 10 月 30 日,香港时间由 LMT 改为 HKT。如果 (a) 您的时区设置为香港时间,并且 (b) 您系统的时区库足够详细以反射(reflect)此特定更改,我预计会出现此症状。

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 ,我熟悉它只是因为它有 highest-scoring answer通过highest-scoring user在堆栈溢出上。那是纯粹的运气。

因为我最初不知道时区,所以谷歌搜索“1904 time change”出现了 this page同年在卢森堡讨论类似的时间变化。世界其他地区可能在同一时间发生了类似的变化,这可能是向现代标准时区过渡的一部分。

Frxstrem 的评论一针见血:Google 搜索“1904 年香港时间变更”找到了 this page .

关于c - mktime() 奇怪地改变了日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24962380/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com