为什么tm_mday从1开始,而struct tm的所有其他元素从0开始?

虽然 answering another question,我告诉OP他需要正确初始化他的struct tm变量,但需要小心,因为他不能简单地使用
struct tm mytime;
memset(&mytime,sizeof(mytime));

因为并非所有struct tm的字段都是有效的.A closer look on struct tm告诉我,它正是struct tm的一个字段,它没有0作为有效值,即tm_mday:

06001

为什么?对于这个元素,决定背后有什么想法,0应该没有有效值???

解决方法

如果您假设以下两个规则,这是有道理的:

>如果允许最简单的显示,则存储从1开始的值,而不必在常见日期格式中添加或减去一个
>在所有其他情况下(或根据格式,第一个规则可以采用任何一种方式),存储从0开始的值

应用规则:

> tm_sec,tm_min,tm_hour从0开始显示,因此从0开始存储.在12小时格式中,第一个小时为12,但其余部分可以从0开始“按原样”显示.
> tm_mday从1开始显示,因此从1开始存储
> tm_mon从24/02/1964等日期开始从1开始显示,但也有意义从0开始存储以便于在1964年2月24日的日期中为数组中的字符串编制索引,因此可以采用任何一种方式 – >从0开始
> tm_year 20世纪年份可以按原样显示为2年格式,例如24/02/64,或者加上1900,没有从1开始有意义的情况
> tm_wday通常通过索引字符串数组来显示,从0开始
> tm_yday没有明确的理由从1开始便于显示,从0开始

所以tm_mday是唯一一种从1开始存储它的明显优势,以便在所有常见情况下显示.

来自C-89 standard的asctime的参考实现与此一致,唯一的调整是将任何值添加到tm_year的1900:

char *asctime(const struct tm *timeptr)
     {
         static const char wday_name[7][3] = {
                  "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
         };
         static const char mon_name[12][3] = {
                  "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
         };
         static char result[26];

         sprintf(result,"%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",wday_name[timeptr->tm_wday],mon_name[timeptr->tm_mon],timeptr->tm_mday,timeptr->tm_hour,timeptr->tm_min,timeptr->tm_sec,1900 + timeptr->tm_year);
         return result;
     }

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...