当answering another question时,我告诉OP他需要正确地初始化他的struct tm
变量,但需要小心,因为他不能简单地使用
struct tm mytime;
memset(&mytime, 0, sizeof(mytime));
因为 * 不是所有 * struct tm
的字段从0
都有效。A closer look on struct tm
向我表明,正好是**struct tm
的一个**字段不具有0
作为有效值,即tm_mday
:
int tm_sec seconds [0,61]
int tm_min minutes [0,59]
int tm_hour hour [0,23]
int tm_mday day of month [1,31]
int tm_mon month of year [0,11]
int tm_year years since 1900
int tm_wday day of week [0,6] (Sunday = 0)
int tm_yday day of year [0,365]
int tm_isdst daylight savings flag
为什么?对于这个元素,0
不应该是有效值的决定背后是什么想法???
3条答案
按热度按时间nvbavucw1#
如果假设以下两个规则,这是有意义的:
应用规则:
tm_sec
、tm_min
、tm_hour
从0开始显示,因此从0开始存储。在12小时格式中,第一个小时为12,但其余小时可以从0开始“按原样”显示。tm_mday
从1开始显示,因此从1开始存储tm_mon
在日期(如24/02/1964)中从1开始显示,但对于日期(如24 th February 1964),从0开始存储以便于在数组中索引字符串也是有意义的,因此可以选择任一方式-〉从0开始tm_year
20世纪年份可以按2年格式显示,例如24/02/64,否则添加1900,从1开始的情况没有意义tm_wday
通常通过索引字符串数组显示,从0开始tm_yday
没有明确的理由从1开始以便于显示,从0开始因此,
tm_mday
是唯一一种从1开始存储以便于在所有常见情况下显示的情况。来自C-89标准的
asctime
的参考实现与此一致,对任何值的唯一调整是将1900添加到tm_year
:y4ekin9u2#
我猜巴比伦人决定用数字
1
来表示一个月的第一天(原因很明显),因为他们还没有发明数字0
。(Same第1年为第一年的原因AC)
从那时起,没有人改变过月份的编号。
bkkx9g8r3#
另一个可能的原因是,
tm_mday == 0
检查可以用来将这样的日期视为“null date”(或“not set”/“not available”),保留通过零初始化语义隐式初始化它的能力,如果为此目的使用了某个非零(比如INT_MIN
)值,则这是不可能的。