I have no problem with the proposed patch to strftime.3 though I'd word the change for %s more like it is in the GNU and POSIX specifications, to make it clear that the value that %s represents as a string is the identical value that mktime() would return if given the same struct tm.
It would also be worth adding something to indicate that the results are unspecified (unlike mktime(), but including the %s conversion which uses mktime() somewhat weirdly) if any of the fields in the struct tm are out of range. Note that the standards actually say out of range of the values specified in <time.h> - which says, for example, that for tm_mday the range is [1..31] which makes sense, some months have 31 days. That would mean that as specified, a struct tm with tm_mday==30 and tm_mon==10 (November, the months are origin 0 ... one of the historical quirks of all of this) would not be considered to have any values which are out of range - which is not really what anyone (implementation, or human) believes to be true. Similarly tm_mon==1 and tm_mday==31 would be in range... That this avoids strftime() producing unspecified results is not the problem (printing "31 Feb 2022" is what would happen in the latter case, that's fine, if idiotic, but gigo). What matters more is when used with mktime() which is only actually permitted to modify the fields which are out of range of what <time.h> secifies (and purely by implication, it isn't written in the standard, other fields which ought to be adjusted to compensate for the field being reduced to be within range). That is, the intent (though it isn't stated) is that one can do tm = localtime(&t); tm->tm_mday += 3; t = mktime(tm); and in addition to that being a kind of baroque way to write t += 86400 * 3; (it does avoid needing to deal with potential overflow of t, since tm_mday is an int, and localtime() is restricted to only put values 1..31 in it, the += 3 cannot overflow, as long as int is at least 7 bits - and nothing allows int to be that small - hence no need for any overflow protection, other than checking the values of t and errno after the mktime()). The resulting struct tm (a value/result parameter) from mktime() is intended to be exactly the same as would reault from a call of localtime(&t) on the resulting t (assuming mktime() did not fail). That is, if the original t represented Feb 28, and not in a leap year, the answer should represent Mar 3 (or Mar 2 in a leap year), not Feb 31 - but it is not clear from the specs that the standard actually allows that to happen. Apologies for the irrelevant side ramble there, none of that has anything do do with strftime.3 The proposed change to tm.3 [aside: wtf is this in section 3? Surely it belongs in section 5 or something ??] I would word differently however. It doesn't really help to talk about "informational" fields, or anything related. I'd simply say something like: When passing a struct tm to a library routine, the fields that it is to access must be set to appropriate values, as defined by that function, other fields need not be initialised. Of course, that then places the burden on asctime(3), mktime(3), and strftime(3) to actually correctly document the fields that are used (and for strftime that means for each conversion specifier, as it is done in the standards, though not necessarily using the same technique - one could instead provide a table of the fields of the struct, and for each, give a list of which conversions use that field (and hence require it to be set). Only the fields that some conversion requires need be mentioned at all - with some text indicating that any other fields of struct tm not mentioned are not required by any conversion (which applies to tm_zone and tm_gmtoff in the current implementation). Anything else accepts a struct tn as an arg as well of course. kre