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

时间:2015-07-13 10:10:55

标签: c time struct mktime

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

struct tm mytime;
memset(&mytime, 0, sizeof(mytime));

因为{em>并非struct tm的所有字段都来自0A closer look on struct tm告诉我,struct tm一个字段没有0作为有效值,即tm_mday:< / p>

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没有有效价值的决定背后的想法是什么?

2 个答案:

答案 0 :(得分:4)

如果你假设以下两条规则,那就有意义了:

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

应用规则:

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

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

来自C-89 standardasctime的参考实施与此一致,是对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;
     }

答案 1 :(得分:0)

我猜巴比伦人决定在一个月的第一天使用数字1(原因很明显),因为他们还没有发明数字0

(第1年是AC第一年的原因相同)

此后,没有人改变月份的编号。