Most definitions of strftime
's %H
, %M
, and %S
specifiers (including those in the ANSI/ISO C Standards) contain language like
%H
is replaced by the hour (24-hour clock) as a decimal number (00-23).
Now, that little notation "(00-23)" at the end tells you the
range of numbers you're going to see if the struct tm
you're
printing was just created by localtime
or gmtime
.
My question concerns the presence or absence of a requirement
that the struct tm
being referenced by strftime
must have been
one just generated by localtime
or gmtime
. I don't think there's
such a requirement, but if there isn't, those notations "(00-23)"
and "(00-59)" don't really have any normative implications for
strftime -- they're more of a misplaced requirement on the values
generated by localtime
and gmtime
.
But if strftime
doesn't restrict the ranges of the various struct tm
fields to their "normal" values, it makes me wonder how much
latitude a push-the-boundaries programmer actually has when
calling strftime
. Are the values as unlimited as they are when
calling, say, mktime
?
To make the question more concrete, it came to me when I found myself writing this code:
time_t dt = t2 - t1;
struct tm *tmp = gmtime(&dt);
if(dt > 86400)
tmp->tm_hour += dt / 86400 * 24;
strftime(etbuf, sizeof(etbuf), "elapsed: %H:%M:%S", tmp);
That is, I'm subtracting two times, and letting gmtime
and
strftime
convert the difference to HH:MM:SS format for me.
But if the time delta was more than a day, I'm not printing it
as days; I'm just lumping it in with the hours (which, it's true,
might end up being a very large number if there were months or
years between t1
and t2
).
So, language lawyer question: Is this legal and portable?
When calling strftime
, are tm_hour
, tm_min
, and the rest
limited to their normal ranges, or not? (Yes, I've tried it,
and nonnormalized values work -- not at all surprisingly --
as expected under the popular implementations, but that's not
the question.)
[Full disclosure: I am posting the same question to the tz mailing list.]
The C11 standard 7.27.3.5/3 says:
If any of the specified values is outside the normal range, the characters stored are unspecified.
Which I take to mean that the input must be normalized for the function to behave correctly; and a conforming implementation of strftime
might operate by naively reading and displaying the values stored in the struct without performing any analysis on them.