time.h
声明 struct tm
具有(以及其他成员)以下内容:
int tm_mon; /* Month [0, 11] (January = 0) */
int tm_mday; /* Day of the month [1, 31] */
int tm_wday; /* Day of the week [0, 6] (Sunday = 0) */
int tm_yday; /* Day of the year [0, 365] (Jan/01 = 0) */
这样的结构可以让你陷入不可能的情况......例如:
tm_mon=0 ; tm_mday=1 ; tm_yday=360
或
tm_year=0 ; tm_yday=1 ; tm_wday=5 ;//1900 年 1 月 1 日是星期一
我很幸运将结构memset
设置为0,然后只设置我想要设置的字段。
我的问题是:是否有一种确定的方式来解释 struct tm
?
我已经对此进行了一段时间的试验,所以这不是一个“如何让我的代码工作”的问题。大多数情况下,我会询问其他经验丰富的程序员使用 struct tm 的经验,并找出任何问题。
最佳答案
Is there a deterministic way that
struct tm
should be interpreted?
是的,大部分。
调用mktime()
解决 struct tm
中的那些不可能的情况 .
同时提及@pm100 ,调用mktime()
将忽略成员.tm_wday
和.tm_yday
并继续解决超出正常范围的其他成员组合,就好像时间是本地时间。
不寻常的“陷阱”时间戳示例包括:
一个成员超出主要范围:减少到主要范围并将超出的部分添加到下一个最重要的成员。根据需要重复。请参阅后面的异常。
2 月 29 日(非闰年)。
.tm_min = 30, .tm_isdst < 0
和.tm_hour
当该区域采用夏令时 (DST) 时,正处于一天 23 小时制的缺失时刻。.tm_min = 30, .tm_isdst < 0
和.tm_hour
是在 25 小时制的一天中,当该区域关闭夏令时时的附加时间。我对
mktime()
的可靠性有疑问处理像.tm_year = INT_MAX/12 + 100, .tm_mon = INT_MIN
这样的病态案例。这种极端情况可能会在不同平台上表现出不同的分辨率(或错误返回值-1)并反射(reflect)实现质量差异。mktime()
返回 -1 表示错误。不幸的是,它也很少返回 -1 来指示有效时间。 C 规范没有提供明确的区分方法。struct tm
可能有除指定 9 以外的其他成员。我见过.tm_nsecs, .tm_usec, .tm_timezone, .tm_tzoffset
或同等物。这就是为什么最好用{ 0 }
进行初始化。或第一个memset(0)
填充struct tm
时的整个对象使用自定义代码。最棘手的 - 当
.tm_year, .tm_mon, .tm_mday
都超出了范围:首先解决哪个?根据顺序,结果会有所不同。 C 确实指定:
the final value of
tm_mday
is not set untiltm_mon
andtm_year
are determined.
ISO 8601确实允许 24:00:00
指日历日结束时的那一刻。那是同一时间0:00:00
第二天的。所以有时,通过 mktime()
减少并不总是理想的。
为了简单和理智起见,讨论 leap seconds被忽略。
关于c - struct tm 成员中的冲突如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75478540/