【问题标题】:mktime shifts a time by one hourmktime 将时间移动一小时
【发布时间】:2015-01-14 09:57:57
【问题描述】:

我遇到了一个关于 mktime 函数的有趣问题。我使用俄罗斯时区 (UTC+03:00) Волгоград, Москва, Санкт-Петербург (RTZ 2) / Volgograd, Moscow, Saint Petersburg/ 并尝试为“7.01.2009 00:00:00”构建 time_t

tm localTM;

localTM.tm_sec = 0;
localTM.tm_min = 0;
localTM.tm_hour = 0;
localTM.tm_mday = 7;
localTM.tm_mon = 0;
localTM.tm_year = 109;

time_t t = mktime(&localTM);

mktime 执行后的日期和时间更改为“6.01.2009 23:00:00”。

我没有问题,然后我为“06.01.2009 00:00:00”或“08.01.2009 00:00:00”构建时间。 如果我将时区切换到另一个时区,“7.01.2009 00:00:00”就不会出现问题。

这个奇怪的原因是什么,我该如何解决这个问题?

【问题讨论】:

  • 俄罗斯的规则变化太多,他们刚刚在 10 月 26 日从 UTC+4 转移到 UTC+3。当您不指定使用的版本以及是否保持更新时,您的操作系统跟踪规则的能力就不清楚了。
  • 我使用的是 Windows 7 Professional,所有最新更新都已安装

标签: windows timezone mktime


【解决方案1】:

在执行到time_t 的转换时,mktime 需要猜测输入是否为 DST(夏令时)。 为此,使用tm.tm_isdst 字段。见man mktime

   tm_isdst  A  flag  that  indicates  whether  daylight saving time is in
             effect at the time described.  The value is positive if  day-
             light  saving time is in effect, zero if it is not, and nega-
             tive if the information is not available.

由于您没有在代码中初始化tm_isdst,因此使用默认值(0),使mktime 认为它处于NO-DST 期间。 要在您的代码中修复它,只需添加

 localTM.tm_isdst = -1

注意 - 逻辑是必要的,因为在某些时刻,存储在 tm 中的“挂钟”信息不足以确定确切的时间。

是的,默认行为是这样的事实有点混乱:)

【讨论】:

    猜你喜欢
    • 2020-10-09
    • 2010-11-07
    • 2013-11-05
    • 1970-01-01
    • 2017-12-17
    • 2014-06-21
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多