c - struct tm 和 mktime() 关于时区转换的接口(interface)契约

标签 c mktime

在运行以下 C 代码时,我注意到 mktime() 在调用时显然会进行一些时区转换。

void process_time(struct tm * pt) {
    printf("pt %02d-%02d-%02d %02d:%02d:%02d\n", pt->tm_year, pt->tm_mon, pt->tm_mday,
            pt->tm_hour, pt->tm_min, pt->tm_sec);

    ret = mktime(pt);

    printf("pt %02d-%02d-%02d %02d:%02d:%02d\n", pt->tm_year, pt->tm_mon, pt->tm_mday,
            pt->tm_hour, pt->tm_min, pt->tm_sec);

    /* more code here */
}

在某些情况下(原来是由于某些 struct tm 成员未正确初始化),我注意到在调用 mktime() 之后,pt->tm_hour 比之前少了一个。本地系统时间是 UTC 以东一小时,因此对应于本地到 UTC 的转换。

根据 this source , struct tm 应该只有通常的 YYYY-MM-DD-hh-mm-ss 字段,除了工作日、一年中的某一天和一个 DST 标志——没有提及时区或 UTC偏移量。

但是,当我检查 Ubuntu 上的结构 (/usr/include/time.h) 时,我注意到两个额外的字段用于 UTC 偏移量和一个时区字符串。

struct tm 的接口(interface)契约是什么?它是否强制执行这些时区转换,如果是这样,在 mktime() 规范化它们之后,struct tm 成员应该如何解释时区?

最佳答案

struct tm的接口(interface)契约是什么? ?

mktime()的关键部分规范是:

The mktime function converts the broken-down time, expressed as local time ... The original values of the tm_wday and tm_yday components of the structure are ignored, and the original values of the other components are not restricted to the ranges indicated above. ... On successful completion, ... components are set to represent the specified calendar time, but with their values forced to the ranges indicated above.
C11dr §7.27.2.3 2

tm_wday 的值和 tm_yday被忽略。成员指定年、月、日、时、分、秒 .isdst贡献,但其他平台指定的会影响结果。这可能包括纳秒、时区、UTC 偏移等成员。

健壮的代码集所有成员。

struct tm t = {0};        // clear **all** members
t.tm_year = 2018 - 1900;  // Assign some members
t.tm_mon = 2 - 1;
t.tm_mday = 1; // today
t.tm_isdst = -1;          // Let system determine if DST applies for this date
process_time(&t);

I noticed that after the call to mktime(), pt->tm_hour was one less than it was before.

这可能是由于 .tm_isdst < 0 .

The value of tm_isdst is positive if Daylight Saving Time is in effect, zero if Daylight Saving Time is not in effect, and negative if the information is not available. §7.27.1 4
Footnote 320: A negative value causes it to attempt to determine whether Daylight Saving Time is in effect for the specified time.

添加.tm_isdstprocess_time() 中的 2 行看看效果。

 printf("pt %02d-%02d-%02d %02d:%02d:%02d  %d\n", 
     pt->tm_year, pt->tm_mon, pt->tm_mday, 
     pt->tm_hour, pt->tm_min, pt->tm_sec, pt->tm_isdst);

how are struct tm members supposed to be interpreted regarding time zones after mktime() has normalized them?

作为规范化的本地时间。

关于c - struct tm 和 mktime() 关于时区转换的接口(interface)契约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48570187/

相关文章:

c - 在 8 秒内检测 16 GB 笔式驱动器上的内容更改

php mktime 对同一日期给出不同的结果?

Linux 上 mktime 的混淆行为?

C函数指针转换为另一个函数指针

c - sigsuspend(),替换设置还是添加?

valgrind 提示 __mktime - 那是我的错吗?

c++ - mktime 仅处理 Clang 上的闰年?

php - 在 PHP exec 中使用 mktime 运行 C 代码

c - 程序堆内存的初始大小

c - C 程序中的段错误(核心转储)