On Tue, Oct 25, 2022 at 14:56:23 +0700, Robert Elz wrote: > Date: Tue, 25 Oct 2022 04:08:13 +0300 > From: Valery Ushakov <u...@stderr.spb.ru> > Message-ID: <Y1c2/di8seq1o...@pony.stderr.spb.ru> > > | strftime(3) %s format is not in ISO C or POSIX, though the rumor is > | that it will be in the next POSIX version. > > It will be. The text is: > > s Replaced by the number of seconds since the Epoch as a decimal number, > calculated as described for mktime( ). [all members] > > For what it is worth, since we are here, tm_zone and tm_gmtoff will be > in the next POSIX as well. [...] > > | The problem though is that mktime(3) is specified to convert tm > | "expressed as local time". > > Yes, that is not a problem though, it is how it is specified to work. > Everything in strftime() takes the struct tm as being in local time. > (That's why NetBSD has strftime_z()).
I'm not very familiar with the lore of this API, but my guess was that strftime(3) was specified the way it was b/c TZ info (except for tm_isdst) was not the official part of struct tm - as you say, the tm_zone and tm_gmtoff are only now being added to it. I further guess that gmtime(3) was there as a surrogate. If we can't standardize the API that provides conversion for an arbitrary, explicitly specified timezone, let's provide at least API for UTC and local time do dodge the "explicitly specified timezone" part. > | The test below produces ("g" is for tm from gmtime, "l" is for tm from > | localtime): > > I am not sure that calling strftime() on something obtained from gmtime() > makes any sense. If one wants UTC conversions, either use strftime_z() > (not a POSIX interface) or set the timezone to UTC (tzset() with TZ="UTC"). I think this circles back to the issue of whether TZ information is in fact kept in struct tm, smuggled in by the implementation - as it's not part of the standard. Now that tm::tm_gmtoff will be official I'm not sure the above argument is really convincing. The tz information is (will be) part of tm, so it at least feels weird that it is explicitly ignored by other parts of the same standard. One can obtain struct tm from gmtime() or from localtime_rz() (or with the equivalent tzset() song and dance) and the standard (will) require TZ info to be part of that struct tm, yet strftime() is still told to ignore those parts, which confuses me. What is the intended composability here? In another thread you said that a man page should just lay out bare facts and let the user figure out how to use the API. Color me stupid. -uwe