[tz] strftime %s

Robert Elz kre at munnari.OZ.AU
Sun Jan 14 01:46:34 UTC 2024


    Date:        Sat, 13 Jan 2024 15:04:31 -0800
    From:        Paul Eggert via tz <tz at iana.org>
    Message-ID:  <cb3042f9-0698-431a-bc9a-542c8aa6d6ca at cs.ucla.edu>

  | This wording doesn't specifically say that strftime must ignore all 
  | information other than the bracketed members and the LC_TIME category; 

Not all information, certainly - but unless you have some way
to guarantee that the aplication has set the unspecified fields
of the tm struct, referencing any of them may be referncing uninit'd
date, and that is undefined behaviour (processor is permitted to
execute the hcf instruction).

  | it merely calls out information that strftime can use.

More importantly it specifies the fields the application must set,
dirctly or indirectly (as by a call to localtime).

  | In general  strftime cannot ignore all the other information,
  | as in general strftime must look at the TZ setting

Only for %s, and that is specified by reference to mktime() which
is where the TZ reuirment appears (via tzset()).  If there is no
use of %s strftime() should not go near TZ.

  | and the LC_CTYPE category.

Yes.   That one is explicit.

  | So the standards' wording (admittedly confusingly) does allow
  | strftime to pay attention to nformation outside the bracketed list.

Implementations are generally permitted to operate however they like.
If you have some way to guarantee that referencing any uninit'd
fields wont have consequences you don't want to have hapoen, then
go ahead and do it.   Generally we assume architectures that don't
trap (or worse) on references to uninit'd memory, but simply return
garbage, so if that's good enough, then fine, go ahead.

  | for %z POSIX 202x/D3 lists "[tm_isdst, tm_gmtoff]" whereas C17 lists 
  | only "[tm_isdst]".

Yes, if you're being strictly C conforming, then you cannot access
tm_gmtoff, as C doesn't demand that field exist, so conforming portable
C applications cannot be expected to have set it.   POSIX does required
it (will require it when this new standard appears) and so applications
written to conform to that standard will know to set that field.
Older applications will not, so accessing it for them is risky.

  | My earlier (hasty) reading would have C17 prohibiting 
  | the use of any member other than tm_isdst to process %z,

Yes.   It (effectively) does.

  | With this in mind, your proposed patch looks like a good approach.

Approach for what, I'm not sure what the proposed patch is, or what
it is intending to fix - as best I can tell, the tzcode strftime()
doesn't really need any changes (unless we want to still attempt to
support applications running on systems without tm_gmtoff - which
has been very few for a long time now).

  | much simpler than other approaches mentioned in this thread that would 
  | add members to struct tm and therefore would be a major pain,

In practice, it is impossible.   struct tm exists in binary form
in thousands of places that can't be updated.   If it weren't for
the fact that tm_gmtoff and tm_zone already exist in essentially every
implementation, and have done for years, there's no way they could
have been added to the standard (and is why it took so long).

Any future struct tm changes are going to need an entire new
structure, and also a whole new set of accessor funxtions (ie:
something to replace localtime() mktime() strftime() ...) and
ideally would be defined in a way which doesn't allow applications
direct access to its members, or to the size of the struct, but
only via the accessor functions (which would then need some form
of "set" and "get" functions to allow acess to the fields).

  | or that would add new functions strftime_z and strftime_lz which
  | would also cause significant pain.

No, adding new funxtions is easy, provided name clashes can be
avoided (which probably means only exposing the names if the
application, one way or another, requests them).

kre



More information about the tz mailing list