[tz] strftime %s

Brooks Harris brooks at edlmax.com
Sat Jan 13 16:43:15 UTC 2024


On 1/13/2024 12:00 AM, Robert Elz via tz wrote:
>      Date:        Fri, 12 Jan 2024 14:47:02 -0500
>      From:        scs at eskimo.com (Steve Summit)
>      Message-ID:  <2024Jan12.1447.scs.0002 at tanqueray.local>
>
>    | And pretty much the only
>    | reason to call localtime or gmtime to construct a struct tm is
>    | so that you can print out a human-readable time string, perhaps
>    | using strftime.
>
> That's not really the case, not in truly portable C code, as
> time_t (in C) has a largely unspecified format and reesolution.
> The only portable way to do arithmetic (perhaps even comparisons,
> though I am less sure about that) is to generate a struct tm,
> operate upon the fields of that, and then if needed, comvert
> back to a time_t.
>
> That's not required of a POSIX time_t which is defined as an
> integer count of seconds, so simple addition of an integer
> containing an interval in seconds achieves the same thing.
>
>    | But, despite their non-human-readableness, time_t values are now
>    | so ubiquitous that they are occasionally of interest to humans,
>    | so at some point along the way, the 'date' command acquired "%s"
>    | as one of its custom output format specifiers.
>
> date +%s isn't (usually) for humans, it is needed for scripts
> to work with time_t values (at least in a POSIX environment
> where time_t's are seconds - which is why %s is in POSIX strftime,
> but not in the C standard, in the latter it is essentially useless
> if defined to simply represent the time_t - it could be defined
> to represent the time_t converted to integral seconds however).
>
> That allows scripts to determine how old something is, by
> subtracting its time_t timestamp from "now" (ie: date +%s).
>
>    | (to my mind, anyway) still vastly preferable to trying to have
>    | strftime handle %s by itself, because strftime just doesn't have
>    | the right information available to it.
>
> It does if the correct elements of the struct are filled in,
> as mktime() can reconstruct the time_t from a struct tm.
> However it does that assuming that the struct expresses the
> current local time (as defined by the TZ setting) - and not
> some other random zone.   There are people who don't understand
> that, and insist that it must also work for other zones - but
> it simply doesn't.
>
>    | I gather from this thread that someone has decided to "solve"
>    | this problem anyway, by officially adding %s to the supported
>    | strftime formats.
>
> Yes, it is in the next POSIX.
>
>    | implementation problem -- but then, I'm not on the Posix
>    | committee, so it doesn't matter what I think.
>
> It isn't so much what committee thinks, but what the implementations
> have done, and essentially all current strftime() implementations
> support %s.
>
>    | I hope that, in the absence of either of these admittedly radical
>    | proposals, Posix is at least mandating tm_gmtoff,
>
> It is.   But strftime isn't allowed to use it to implement %s
> as old applications can't be relied upon to give tm_gmtoff a value
> before calling strftime() as tm_gmtoff didn't used to be required.
> Hence if strftime() accessess tm_gmtoff (except possibly for %z)
>
> kre
I like Steve's idea of including a tm_time_t member in struct tm. I use 
something like this in my internal processes.

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.

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.

I'm not sure how feasible it is but perhaps the Posix folks might 
consider the idea.

-Brooks






More information about the tz mailing list