Maximilian said:
Maximilian said:
I write adventure game in language C and when I want to format
date, it is "Numerical result out of range".
For example [snip]
s: (null)
errno: 34 (Numerical result out of range)
[...]
Hello, Keith Thompson!
Since lcc-win is developed by jacob navia, who has been involved in
some rather heated discussions here about the behavior of asctime() in
corner cases, including the particular case you use in your program, I
have to wonder whether this is a serious question.
That is very mysterious. I searched comp.lang.c in google and
found nothing. I thought lcc-win32 uses msvcrt.dll.
I believe lcc-win32 uses its own runtime library. I don't know
whether it also uses msvcrt.dll, but jacob has said here that lcc-win
has its own implementation of astime(). If you're curious, you can
ask in comp.compilers.lcc.
That program (tm_mday=0) is only example. asctime() also returns NULL
if tm_mday is > 31, but not if date is for example February 31.
What I wonder is why I can not format "alien" dates with asctime(). In
my game all months have 32 days (because it's power of 2). Can strftime()
format months with 32 days, everywhere? What means "Numerical result" in
context of asctime()?
It seems fairly obvious that the numeric result you're giving it for
the day of the month is outside its range of 1..31. Whether the
implementation is allowed to reject such a value is another question.
Yes please, I want to know!
Ok. You can get a copy of a recent draft of the standard at
<
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf>; asctime()
is described in 7.23.3.1. The definition hasn't changed significantly
since the 1989 ANSI C standard.
The behavior of asctime is defined, not in terms of hours, minutes,
seconds, and so forth, but by a specific algorithm, presented in C
code, to which it must be equivalent. An implementation that uses
that algorithm, or an equivalent one, will produce certain
well-defined results for certain input values -- even if those input
values are not sensible. For example, the day of the month is
formated with "%3d", which means that any value for mday in the range -99 to
+999 will fit in that 3-character field; longer values may cause a buffer
overrun *unless* the year, which is printed with "%d" takes up fewer
spaces.
jacob has rather strongly expressed the opinion that the input values
are required to be within the "normal ranges" defined in 7.23.1 (a
section that doesn't mention asctime), and that an implementation is
therefore free to behave differently (say, by returning NULL and
setting errno) if, for example, you give it a tm_mon value of 0, even
though the presented algorithm has well-defined behavior in that case.
(We've had several lengthy and unpleasant flame wars on that topic,
both here and in comp.std.c. You can understand my suspicion when
someone brings up an unusual example, using jacob's compiler, that
illustrates the very point that has been disputed. If someone wanted
to resurrect that old flame war, just for the fun of watching people
argue about it all over again, your original article might be an
effective way to do it. We do have people here who deliberately
disrupt this newsgroup. I hope that's not what you're doing. Search
for "asctime" in this newsgroups archives.)
So, having said all that, and assuming you're really interested in a
solution to your stated problem, my recommendation is *not* to use
asctime(). Setting aside the debates about how asctime() is required
to behave, it's primarily intended to handle dates that are valid in
the real-world Gregorian calendar. And it produces a rigid and
somewhat obsolete format. It automatically ends the string with a
new-line, it ignores localization, always using English abbreviations
for weekdays and months, and it uses an inconvenient ordering.
If you want to format alien dates, such as February 31 or January 0,
just format them yourself using sprintf(). (strftime() won't work for
your purposes; the result when any input values are outside their
"normal ranges" is unspecified.)