This makes sense if you accept the following two rules:
- Save the value starting with 1 if this allows you to get the simplest display without having to add or subtract one of the common date formats.
- In all other cases (or when the first rule can go anyway depending on the format), save the value starting from 0
Rule Application:
tm_sec , tm_min , tm_hour displayed starting at 0, so save it starting at 0. In a 12-hour format, the first hour is 12, and the rest can be displayed โas isโ, starting from 0.tm_mday displayed starting at 1, so saving starts at 1tm_mon displayed starting from 1 in dates, such as 24/02/1964, but it also makes sense to store starting from 0 for the convenience of indexing rows in an array for dates such as February 24, 1964, so you can go anyway โ start with 0- 20th century
tm_year can be displayed as is in a two-year format, for example. 24/02/64, or add 1900, there is no case when starting with 1 makes sense tm_wday Usually displayed by indexing a string array starting at 0tm_yday There is no clear reason to start working with 1 for ease of display, starting at 0
So, tm_mday is the only case when there is a clear advantage for storing it starting from 1 for ease of display in all common cases.
The reference implementation of asctime from C-89 standard is consistent with this, the only setting for any of the values โโrelated to add 1900 to tm_year :
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; }
source share