Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/lib/libc/time



    Date:        Wed, 17 Apr 2019 22:47:04 -0400
    From:        christos%zoulas.com@localhost (Christos Zoulas)
    Message-ID:  <20190418024704.6A10717FDA1%rebar.astron.com@localhost>

  | Put it as part of the documentation and say that it is a bug that there
  | is no way to get one referencing a particular point in time.

Anything which makes it clear that gettzname() (which is really
just an alternative to use of the dumb non-thread-safe tzname[]
array) should be avoided wherever possible is a good thing.

But we don't need anything new, we have all that is needed now,
in localtime() (and its differently arg'd semi-clones) which take
a time, and a timezone (for simple localtime() it is whatever TZ
says, or local wallclock time if TZ is not set) and a locale (again,
that is the current default locale for simple localtime()) and
return the associated zone abbreviation in tm_zone.

The problem is that a standards conforming C application cannot
assume that field exists, not that we need something new (which a
conforming application would not be able to assume exists either).

It is even worse, as you pointed out when I suggested using tm_zone
for strftime()'s %Z conversion - we cannot (in libc) assume that the
application has set the tm_zone field (that is, normally, that the struct tm
came from localtime) - it is perfectly acceptable for an application
to do

	tm.tm_mday = 3;
	tm.tm_mon = 3 - 1;
	tm.tm_year = 2019 - 1970;

	tm.tm_hour = 13;
	tm.tm_min = 23;
	tm.tm_sec = 0;

	tm.tm_isdst = -1;

	strftimebuf, sizeof buf, "%c %Z". &tm);

to get the local way to get the current locale's standard representation
of 20190303T132300 formatted into "buf" with the zone abbreviation appended.

I suppose we could do mktime() on the tm passed in, and then localtime()
on the result, and then we could use the resulting tm_zone, but that
sounds like a lot of work, particularly for applications (the common case)
where the tm passed to strftime resulted from localtime() already.

I wonder if we could add a new hidden field to struct_tm to contain a
checksum of the data - then we'd be able to tell (fairly reliably) whether
a struct tm that we're passed is the result of a previous localtime()
call or not.    But no, we cannot, the size of struct tm is part of the
API, and cannot really ever be changed (at the very least that would be
a libc major version bump type event.)   Nor can we reuse a pointer field
that's already it (say tm_zone) to refer to some external appended struct
without losing that additional memory when a tm gets freed (and that
wouldn't work anyway, as many apps assume tm_zone is the zone name).

This stuff is really all ugly, what we really need is a whole new,
properly designed, set of routines that operate in parallel with what
we have now, which might one day be standardised, and which operate
correctly (which includes having proper purpose designed allocate and
free routines, along with either an opaque struct and asseccor routines,
or enough padding that the contents can be changed when needed.)

kre



Home | Main Index | Thread Index | Old Index