[tz] strftime %s

Guy Harris gharris at sonic.net
Sat Jan 13 22:47:26 UTC 2024


On Jan 13, 2024, at 2:27 PM, Brooks Harris <brooks at edlmax.com> wrote:

> On 1/13/2024 4:09 PM, Guy Harris wrote:
>> On Jan 13, 2024, at 12:39 PM, Brooks Harris <brooks at edlmax.com> wrote:
>> 
>>> On 1/13/2024 3:19 PM, Guy Harris wrote:
>>> 
>>>> Given that mktime() cannot determine whether it's been set, this means that mktime() must *always* do the conversion work.
>>> Only if localtime() hasn't already set it.
>> Again, how is mktime() to *reliablg* know whether it's been set?  Shall another element be added to the structure, containing a bitset of elements with 0 meaning "not set" and 1 meaning "set"?  And how is mktime() to know that the bitset has correctly been set?
> 
> mktime() would set it regardless. I doesn't need to know prior state since its calculating from the broken-down-time.

In other words, we should replace

> However, as you point out, you still need mktime() to compute the current time_t in cases where parts of the broken-down-time have been intentionally altered. mktime() could update the tm_time_t member.

with

	mktime() will never use the tm_time_t member and will always set it.

>>> But applications must be careful to be sure it's set to the current value representing the broken-down-time. Maybe some sort of 'state' flag is needed, like "not set", "set by localtime", "set by mktime()"
>> And how are you to ensure whether the state flag has been set?  Perhaps an additional state flag, indicating the state of the first state flag?  (I'm sure you can see where that takes you.)
> 
> Yes. I use things like that to flag if my app has initialized some variable to some default value.

In that case, you're trusting yourself to properly maintain the flag.  However...

> But, yes, it doesn't really flag "is valid now". The app has to keep track of that.

...in *this* case the *library* would have to trust *arbitrary* programmers to do that, and relying on *existing* code, written before any presence flags were in struct tm, that uses, for example, mktime(), can't be done.

>> This all sounds like a lot of complication for *not* a lot of benefit;
> 
> Seems to me the benefit is keeping the tm_time_t value coupled to the broke-down-time. Localtime() can set that so a call to mktime() isn't needed.

	...

> It's not about speeding mktime() but keeping the tm_time_t value coupled to broken-down-time in many instances instances of struct tm.

In other words, we should ignore

> it means a function such as GetUT(tm* ptm) can just return the tm_time_t value. This makes many typical operations simple and fast. It seems straight forward that localtime() could set tm_time_t.

because

	1) if you have a struct tm where you know for certain that tm_time_t is set, you can just fetch the value without bothering with a GetUT() function;

	2) otherwise, you have to call mktime() anyway.

Unfortunately, strftime() can only use the tm_time_t member if it knows for certain it's been set and, in general, it has no idea what routine filled in the structure, so it has no idea whether tm_time_t has been set.

>> given that 1) the majority of calls to mktime() are, as far as I know, calls made in order to *derive* a time_t from a date-and-time-of-day value for which you *don't* already know the time_t and 2) trying to make it possible for mktime() to determine whether tm_time_t has been set is complicated and will end up relying on people writing code carefully *and* probably changing existing code.
> 
> localtime() sets it, and mktime() sets it. Whichever last called has set it.

What if the struct tm was filled in by some *other* code, and the structure is untouched either by localtime() or mktime()?

And what if that's in *existing* code that calls strftime("%s"), which obviously won't set tm_time_t because *it didn't exist at the time the code was written*?


More information about the tz mailing list