strftime("%Z") invalidated by TZ change: is this a fair restriction?
eggert at twinsun.com
Tue Jun 12 14:34:59 UTC 2001
> From: Jonathan Lennox <lennox at cs.columbia.edu>
> Date: Mon, 11 Jun 2001 16:01:10 -0400 (EDT)
> If a 'struct tm' broken-down time structure is created by localtime() or
> localtime_r(), or modified by mktime(), and the value of the "TZ"
> environment variable is subsequently modified, the results of the %Z and
> %z strftime() and wcsftime() conversion specifiers are undefined, when
> strftime() or wcsftime() is called with such a broken-down time structure.
> If the broken-down time structure is subsequently modified by a successful
> call to mktime(),
or by localtime_r()
> the results of these conversion specifiers are once
> again defined.
> If a 'struct tm' broken-down time structure is modified by gmtime(),
or by gmtime_r()
> it is implementation-defined whether the result of the %Z and %z
> strftime() and wcsftime() conversion specifiers shall refer to UTC
> or the current local time zone, when strftime() or wcsftime() is
> called with such a broken-down time structure.
I would make it undefined rather than implementation defined.
Otherwise, you'll need to the address the issue of what happens if TZ
is changed between the invocation of gmtime and the invocation of
strftime with %Z.
> I think it's too late to get this restriction into the Austin Group revised
> POSIX spec
It's not too late to file an interpretation request against the
current standard, with a note that the same problem occurs in the
latest draft (and mentioning the new functionality with %z etc). You
can file a request by visiting <http://pasc.opengroup.org/interps/>.
I would do it now, while you're thinking about it.
> I don't see any sensible way
> to set tm_zone, for struct tm's produced by reentrant timezone functions,
> that doesn't end up leading to free pointer dereferences following
If you have control of struct tm, you can make tm_zone of type char
rather than char *, and insist on a limit for time zone abbreviations.
POSIX allows this limit; it's called TZNAME_MAX, which POSIX requires
to be at least 6. If you do this, you don't need to worry about
pointer dereferences. Admittedly it's not nice to have arbitrary
limits. I would make the limit at least 7 myself.
More information about the tz