令人困惑的mktime在Linux上的行为?

时间:2011-09-16 14:14:24

标签: c linux mktime datetime

我在Suse 10中使用mktime(struct tm *)函数。

现在,当启用夏令时时,我注意到一些奇怪的行为。假设我已经启用了夏令时,从9月15日18:10开始,白天校正为30分钟。现在,当我调用具有日期为9月15日18:10并且tm_isdst设置为0的tm结构的mktime时,我只在tm_isdst设置为1的情况下返回tm结构中的相同值。

但是,如果将日期作为9月15日18:10传递并且tm_isdst设置为1,那么我发现时间已更改为17:40。 tm结构中的这种校正在9月15日18:10到9月15日18:40之间的时间内被注意到,但在此之后没有发生时间校正并且仍然启用了标记。即使我在9月16日18:10过了日期,也没有时间纠正,只有dst标志保持启用状态。

我完全糊涂了。这是mktime的正确行为吗?

2 个答案:

答案 0 :(得分:6)

如果DST的当地时间改变30分钟,那么每年一次有30分钟的本地时间,一次是发生两次(一次是DST,一次是没有),另外30分钟是从未发生(当时间改变时会跳过它)。

因此,当时钟被设置回的30分钟内的本地时间是不明确的,除非指定DST是否生效;他们可以对应的时间有两个实际时刻。

时钟提前30分钟内的当地时间无效;没有实际的时间可以对应(虽然转换可能仍然是通过假设DST生效,或者没有生效)。

因此,对于某些本地时间(忽略DST状态),可能会有多个相应的UTC时间,但对于任何给定的UTC时间,只有一个可能的本地时间(如果正确考虑了DST调整)。

当您致电mktime时,它会将您提供给它的当地时间转换为time_t,就像DST生效或不生效一样,具体取决于tm_isdst的值。您获得的校正值基于此转换的反向,系统将根据其是否在转换时生效DST的想法确定您是获得DST时间还是非DST时间。你给它的时间和你回来的时间实际上代表了相同的时刻,但是由于不同的DST状态而与UTC的偏差不同。

所以是的,这是mktime的正确行为。根据它如何正确表示你给它的时间的想法,它应该规范化结构中的值。

这也说明了为什么要小心使用本地时间跟踪实际事件 - 如果DST状态或与UTC的偏移没有与时间一起保存,则某些本地时间值可能不明确。

答案 1 :(得分:0)

查看this answer,看看是否有帮助。另外,系统时区偏移是什么?通过运行检查:

date +%z