While answering another question, I told the OP he needs to initialize his struct tm
variable correctly but needs to be careful because he couldn't simply use
struct tm mytime;
memset(&mytime, 0, sizeof(mytime));
because not all fields of struct tm
are valid from 0
. A closer look on struct tm
showed me that it is exactly one field of struct tm
that doesn't have 0
as valid value, namely 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
Why? What were the thoughts behind the decision that for this very element, 0
shall be no valid value???
It makes sense if you assume the following two rules:
Applying the rule:
tm_sec
, tm_min
, tm_hour
displayed starting from 0 so store starting from 0. In 12-hour format the first hour is 12, but the rest can be displayed "as-is" by starting from 0.tm_mday
displayed starting from 1 so store starting from 1tm_mon
displayed starting from 1 in dates like 24/02/1964, but also makes sense to store starting from 0 for ease of indexing strings in an array for dates like 24th February 1964, so could go either way -> start from 0tm_year
20th century years can be displayed as-is in 2 year format e.g. 24/02/64, or else add 1900, no case where starting from 1 makes sensetm_wday
Usually displayed by indexing a string array, start from 0tm_yday
No clear reason to start from 1 for ease of display, start from 0So tm_mday
is the only case where there is a clear advantage to storing it starting from 1 for ease of display in all common cases.
The reference implementation of asctime
from the C-89 standard is consistent with this, the only adjustment to any of the values being 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With