为什么mktime()需要知道夏令时?

时间:2017-11-16 14:44:57

标签: c datetime

因此mktime()返回time_t值,该值定义为“表示自UTC时间1970年1月1日00:00开始经过的秒数的整数值”(source) 。我可以使用time_t将日期转换为mktime()值。例如,要将日期10-Sep-2017 08:34:56转换为time_t,我会执行以下操作:

struct tm tm;
time_t tv;

tm.tm_sec = 56;
tm.tm_min = 34;
tm.tm_hour = 8;
tm.tm_mday = 10;
tm.tm_mon = 8;
tm.tm_year = 117;
tm.tm_isdst = ????;

tv = mktime(&tm);

现在我不明白的是tm_isdst参数背后的想法:它被描述为“一个标志,指示夏令时是否在所描述的时间生效” (source)。

这个描述让我感到有些困惑,因为我认为我在struct tm中描述的时间实际上已经是UTC时间,而我想要的time_t值来自mktime() {1}}也是UTC。但是UTC时间不会因季节的变化而变化,那么为什么mktime()需要为夏令时烦恼呢?使用UTC而不是本地时间的优势不是我不必为夏令时烦恼吗?那么为什么我必须设置tm_isdst呢?

我确信答案很简单,但目前我没有看到它。有人可以提供一个简单的示例,说明为什么mktime()需要tm_isdst参数将特定日期和时间转换为time_t值?

3 个答案:

答案 0 :(得分:6)

DST是否有效会更改纪元时间,因为mktime使用当前时区来确定时间。

例如,如果我用1/1/70 00:00:00填充tm,如下所示:

tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
tm.tm_mday = 1;
tm.tm_mon = 0;
tm.tm_year = 70;
tm.tm_isdst = 0;

tv的值为18000,因为我的时区是GMT-5(18000 = 3600 * 5)。如果我将tm_isdst的值更改为1,则tv将设置为14400(3600 * 4)。

tm_isdst设置为-1将查看本地时区数据库,以查看DST是否对给定的日期/时间有效。

答案 1 :(得分:1)

  

现在我不明白的是tm_isdst参数背后的想法:   它被描述为“指示夏令时是否为标志的标志   在“(来源)。

所描述的时间生效      

这个描述有点令我困惑,因为我的意见   我在struct tm中描述的时间实际上已经是UTC了   时间

嗯,那是你的主要问题。根据您已链接的文档,mktime()会将表示为本地时间的时间结构转换为time_t

  

我想从mktime()得到的time_t值也是UTC。

再次根据文档,当time_t被解释为绝对时间时,它表示自纪元以来经过的秒数,在UTC ,所以这确实是你的意思来自mktime()。但这意味着,通常情况下,两个表示形式之间存在时区和可能的日光节省差异。

C库依赖于适用于本地时间的时区的上下文本地化数据,但是虽然它知道夏令时的当前规则,但它不一定知道在指定时间生效的规则。此外,在白天时间和标准时间之间的转换中存在边缘情况。出于这些原因或其他原因,您需要告诉mktime()给定的时间是指夏令时还是标准时间。

  

但UTC时间不随季节的变化而变化,为什么呢   mktime()需要打扰夏令时吗?

因为mktime()接受当地时间作为输入。

  

不是   使用UTC而不是我不需要的本地时间的优势   打扰夏令时?

这是其中一个优点,是的。

  

那么为什么我要设置tm_isdst   然后?

因为mktime()接受当地时间作为输入。

答案 2 :(得分:0)

struct tm可以被视为timestamp

示例:当时区从白天时间到标准时间时,"天"有25个小时,struct tm需要的信息不仅仅是" Y-M-D h:m:s"。

当地时间可能是白天时间凌晨2:30,然后是1小时后标准时间凌晨2:30。 .tm_isdst对区分这种情况特别有用。请注意,.tm_isdst与所有时间戳相关。

由于struct tm本身不包含时区(该信息存在于其他地方),.tm_isdst旨在提供标准时间或白天时间的时间戳指示(甚至未知标准/日光)。

如果.tm_isdst设置为-1(未知)且时区为UTC,那么期望的是,对于所有时间戳,它就好像.tm_isdst == 0