I tried using strptime() to parse dates in the ISO 8601 format (specified by "%F" or "%Y-%m-%d"), but when i read from the result struct tm i get absurd values for time, minutes and seconds. Here is an example code and the result:
char *s_date = (char *)malloc(sizeof(char) * 255);
scanf("%s", s_date);
struct tm bd_date;
strptime(s_date, "%Y-%m-%d", &bd_date)
printf("%d-%d-%d %d:%d:%d\n", (bd_date.tm_year + 1900), (bd_date.tm_mon + 1), bd_date.tm_mday, bd_date.tm_hour, bd_date.tm_min, bd_date.tm_sec);
The resulting output for the input "1990-05-01" is: 1990-5-1 2007659173:32766:1076394855, which show illegal values for tm_hour, tm_min and tm_sec. What am i doing wrong? is there something i'm missing? I though strptime() would automatically set the unused fields in the format to 0, but it seems like this isn't the case.
Apple’s man page for strptime
explicitly says:
If the
format
string does not contain enough conversion specifications to completely specify the resultingstruct tm
, the unspecified members oftimeptr
are left untouched. For example, if format is “%H:%M:%S
”, onlytm_hour
,tm_sec
andtm_min
will be modified.
The Linux man pages are not as explicit but are consistent with this:
In principle, this function does not initialize
tm
but stores only the values specified. This means thattm
should be initialized before the call.
The POSIX standard, which both Apple’s macOS and Linux seek to conform to, has neither of the above nor similar text in the 2008 version I have on hand. It is simply silent about whether other structure members are modified or the structure is initialized.
So, at least in some implementations, strptime
does not modify members for which there is no corresponding descriptor in the format string. E.g, if there is no descriptor for hour such as %H
, it does not modify the hour member of the structure. If you want those members set, you can set them before calling strptime
.