在运行以下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
比一个struct tm
少一个以前。本地系统时间是UTC以东一小时,因此对应于本地到UTC的转换。
根据this source,/usr/include/time.h
除了工作日,一年中的某一天和DST标志外,应该只有通常的YYYY-MM-DD-hh-mm-ss字段 - 没有提及时区或UTC偏移量。
但是,当我在Ubuntu(struct tm
)上检查结构时,我注意到两个额外的UTC偏移字段和一个时区字符串。
struct tm
的接口合约是什么?它是否要求这些时区转换,如果是,那么在mktime()
对其进行规范化后,tail -f "scheduler_$(date '+%m%d%y').log" | perl -pe 's/^/$_=qx(date +%T_); chomp; $_/e'
成员应该如何解释时区?
答案 0 :(得分:2)
struct tm
的接口合约是什么?
mktime()
规范的关键部分是:
mktime函数转换细分时间,表示为本地时间 ...将忽略结构的
tm_wday
和tm_yday
组件的原始值,并且其他组件的原始值不限于上述范围。 ......成功了 完成,...组件设置为表示指定的日历 时间,但他们的价值被强制到上述范围 C11dr§7.27.2.32
忽略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);
我注意到在调用mktime()之后,pt-> tm_hour比之前少了一个。
这可能是由于.tm_isdst < 0
造成的。
如果夏令时生效,则
tm_isdst
的值为正,如果夏令时不生效,则为零,如果信息不可用,则为负。 §7.27.14
脚注320:负值使其尝试确定夏令时是否在指定时间内有效。
将.tm_isdst
添加到process_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);
在
struct tm
对其进行规范化后,mktime()
成员应该如何解释时区?
作为规范化的当地时间。
答案 1 :(得分:1)
您询问了tm_gmtoff
和tm_zone
。这些是struct tm
的非标准添加,虽然它们非常有用且非常常见。它们在mktime
的输入时被忽略,但在输出上设置。它们可能与你看到的不寻常的结果无关。