[tz] [PROPOSED 2/2] strftime: conform better to POSIX+
Paul Eggert
eggert at cs.ucla.edu
Thu Aug 13 23:18:13 UTC 2020
On 8/12/20 6:25 AM, Robert Elz wrote:
> I think it might be just %Z (rarely) and %p (sometimes) which ever
> produce an empty string. How many of those other APIs would ever
> be given either "%Z" or "%p" as their arg?
It's pretty common to design a general-purpose API that is a wrapper around
strftime. For example, Emacs has a function 'emacs_nmemftime' that is a wrapper
around strftime that also allows formats containing NUL bytes (as these are
allowed in Emacs strings). An Emacs Lisp program supplied by the user can invoke
(format-time-string "%p") which invokes emacs_nmemftime which in turn invokes
strftime with a "%p" argument. (The actual code is a bit more complicated than
this, but for now let's assume this simpler version.)
Now, emacs_nmemftime could be modified to treat formats like "%p%Z" as special
cases, and format " %p%Z" instead and discard the leading space in the output.
Or, we could modify emacs_nmemftime to always make a copy of the format with an
extra space in it, call strftime, and then remove the leading space in the
result. Or, we could document 'format-time-string' to mishandle formats like
"%p%Z" in some cases.
But none of these alternatives are good, for obvious reasons. They're all hacks
to work around the deficiency in the C11 strftime API. Since POSIX is fixing
strftime errno deficiencies anyway in other areas, by defining what to do with
out-of-range times, it might as well fix this deficiency with "%p" too, while
it's at it.
> The problem with this one is that all implementations need to support it,
> or it is worthless.
That same objection applies to the EOVERFLOW errno change that is already in the
POSIX strftime draft, as well as to many of the other changes in the POSIX
draft, so evidently it's not a fatal objection.
> [for mktime] ... In most cases it is safe to simply assume that won't be the
> case, and simply treat -1 as the error indicator only
That isn't safe in general-purpose routines.
> when more is needed, the check is not all that difficult
> (after a successful return, which is what it would be if the -1 indicates
> that 1969 date, the tm has been normalised, Dec 31, 1969 was a Wednesday,
> so set tm_wday to 0, and then check if on return it has become 3 or 4
I've used that hack too, but neither POSIX nor C11 require the hack to work.
What I'd propose is that the standard specifies that mktime must not not update
tm_yday when it fails. This matches all implementations that I know of, and
allows the hack to work. The variant that I use is to set tm_yday to -1 before
calling mktime, and test whether it's negative afterwards.
> Another way, if -1 is returned, is to take the original struct tm
> do tm_sec++ and then mktime() again.
This won't work if tm_sec == INT_MAX.
More information about the tz
mailing list