Mientras respondía otra pregunta , le dije al OP que necesita inicializar su variable struct tm correctamente, pero que debe tener cuidado porque no puede simplemente usar
struct tm mytime; memset(&mytime, 0, sizeof(mytime)); porque no todos los campos de struct tm son válidos desde 0 . Una mirada más cercana a struct tm me mostró que es exactamente un campo de struct tm que no tiene 0 como valor válido, a saber, 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
¿Por qué? ¿Cuáles fueron los pensamientos detrás de la decisión de que para este mismo elemento, 0 no sea un valor válido?
Tiene sentido si asumes las siguientes dos reglas:
Aplicando la regla:
tm_sec , tm_min , tm_hour muestran a partir de 0, así que almacene a partir de 0. En el formato de 12 horas, la primera hora es 12, pero el resto se puede mostrar "tal cual" comenzando desde 0.tm_mday se muestra a partir de 1, por lo que se almacena a partir de 1tm_mon se muestra a partir de 1 en fechas como 24/02/1964, pero también tiene sentido almacenar a partir de 0 para facilitar la indexación de cadenas en una matriz para fechas como 24 de febrero de 1964, por lo que podría ir en cualquier dirección -> comenzar desde 0tm_year años del siglo XX se pueden mostrar tal cual en formato de 2 años, por ejemplo, 24/02/64, o agregar 1900, ningún caso en el que comenzar desde 1 tenga sentidotm_wday Por lo general, se muestra al indexar una matriz de cadenas, comienza desde 0tm_yday No hay una razón clara para comenzar desde 1 para facilitar la visualización, comience desde 0 Por lo tanto, tm_mday es el único caso en el que existe una clara ventaja de almacenarlo a partir de 1 para facilitar la visualización en todos los casos comunes.
La implementación de referencia de asctime del estándar C-89 es consistente con esto, el único ajuste a cualquiera de los valores es agregar 1900 a 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; }Supongo que los babilonios decidieron usar el número 1 para el primer día de un mes (por razones bastante obvias) porque aún no habían inventado el número 0 .
(La misma razón por la que el año 1 es el primer año AC)
Desde entonces nadie cambió la numeración de los meses.