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

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

struct tm mytime;
memset(&mytime, 0, 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;
     }
相关文章
相关标签/搜索