首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇怪的mktime()行为

奇怪的mktime()行为
EN

Stack Overflow用户
提问于 2019-04-29 12:27:16
回答 2查看 236关注 0票数 1

为什么mktime()转换31/03/2019 02:00到01:00与tm.tm_isdst =1与CET时区?

我觉得这是个无效的组合。

代码语言:javascript
复制
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

void reset(struct tm* tm){
    (*tm) = (const struct tm){0};

    tm->tm_sec = 0;
    tm->tm_min = 1;
    tm->tm_hour = 2;
    tm->tm_mon = 2;
    tm->tm_mday = 31;
    tm->tm_year = 2019 - 1900;
}

int main(int argc, char **argv)
{
    struct tm   tm;
    int secs;

    reset(&tm);
    printf("Before mktime\n");
        printf(" %04d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec);

    tm.tm_isdst = 0;
    secs = mktime(&tm);
                printf("After mktime tm.tm_isdst = 0;\n");
    printf(" %04d-%02d-%02d %02d:%02d:%02d TZ=%s , tm_isdst = %d, timestamp=%i\n", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_zone, tm.tm_isdst, secs);

    reset(&tm);
    tm.tm_isdst = 1;
    secs = mktime(&tm);
    printf("After mktime tm.tm_isdst = 1;\n");
    printf(" %04d-%02d-%02d %02d:%02d:%02d TZ=%s , tm_isdst = %d, timestamp=%i\n", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_zone, tm.tm_isdst, secs);

    reset(&tm);    
    tm.tm_isdst = -1;
    secs = mktime(&tm);
    printf("After mktime tm.tm_isdst = -1\n");
    printf(" %04d-%02d-%02d %02d:%02d:%02d TZ=%s , tm_isdst = %d, timestamp=%i\n", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_zone, tm.tm_isdst, secs);

    return 0;
}

输出:

代码语言:javascript
复制
% date
Sun Mar 31 06:50:42 CEST 2019
% test_mktime
Before mktime
 2019-03-31 02:01:00
After mktime tm.tm_isdst = 0;
 2019-03-31 03:01:00 TZ=CEST , tm_isdst = 1, timestamp=1553994060
After mktime tm.tm_isdst = 1;
 2019-03-31 01:01:00 TZ=CET , tm_isdst = 0, timestamp=1553990460
After mktime tm.tm_isdst = -1
 2019-03-31 03:01:00 TZ=CEST , tm_isdst = 1, timestamp=1553994060
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-29 13:13:18

  1. 209-03-31 02:01:00 CET (is_dst = 0,UTC+1)不存在,但相当于209-03-31: 01:01:00协调世界时(世后1553994060秒),相当于2019年-03-31: 03:01:00 CEST (is_dst = 1,UTC+2)。
  2. 209-03-31 02:01:00CEST (is_dst = 1,UTC+2)不存在,但相当于协调世界时209-03-31 00:01:00 (世后1553990460秒),相当于欧洲东部时间209-03-31: 01:01:00 (is_dst = 0,UTC+1)。(注: 1553994060 - 1553990460 = 3600,相差1小时。)
  3. 对于is_dst = -1,该实现试图找出夏令时是否有效,但自2019年-03-31 02:01:00对CET和CEST都同样无效,它只选择一个或另一个。在这种情况下,假设输入是在标准时间2019-03-31 02:01:00 CET (is_dst = 0,UTC+1),这是不存在的,但相当于209-03-31 01:01:00协调世界时(世后1553994060秒),相当于2019年-03-31 03:01:00 CEST (is_dst = 1,UTC+2)。
票数 2
EN

Stack Overflow用户

发布于 2019-04-29 14:19:26

由于2019年3月31日02:00是DST改变CET / CEST区域的时间,在该日期2小时的时间不用于该地区的计时。mktime是用来规范输入struct tm中的数据的,这在这里起作用。

具体来说,

  • 如果时间戳2019-03-31 02:01:00按照标准时间解释,换句话说,是01:01:00之后一小时的时间,那么它对应于209-03-31 03:01:00 CEST。正如您的程序所示,struct tm就是这样规范化的。返回值对应于该时间。
  • 如果时间戳2019-03-31 02:01:00是根据夏令时间解释的,换句话说,是指在03:01:00之前一小时的时间,那么它就相当于2019年-03-31: 01:01:00 CET。正如您的程序所示,struct tm就是这样规范化的。返回值对应于该时间,并表示比另一种情况下返回的值早3600秒的时间。
  • 如果您指定未知给定的时间是否被解释为DST有效,那么mktime必须猜测。在大多数时间和日期中,它将根据DST对该日期和时间是否有效进行选择,但在这里不会得到任何答案。在我看来,它在这里解释标准时间比夏令时更合理,因为这似乎更有可能是对提供这种输入的程序的期望。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55903387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档