On Sat, May 27, 2017 at 11:46 PM, Jeff King <p...@peff.net> wrote:
> On Sat, May 27, 2017 at 06:57:08PM +0200, Ævar Arnfjörð Bjarmason wrote:
>
>> There's another test which breaks if we just s/gmtime/localtime/g. As
>> far as I can tell to make the non-local case work we'd need to do a
>> whole dance where we set the TZ variable to e.g. UTC$offset, then call
>> strftime(), then call it again. Maybe there's some way to just specify
>> the tz offset, but I didn't find any in a quick skimming of time.h.
>
> There isn't. At least on _some_ platforms, the zone information is
> embedded in "struct tm" and stored by gmtime() and localtime(), but the
> fields aren't publicly accessible. Which is why your patch worked for
> format-local (it swaps out gmtime() for localtime() which sets those
> fields behind the scenes). But:
>
>   - I'm not sure that's guaranteed by the standard; strftime() might get
>     its zone information elsewhere (if it needs to reliably distinguish
>     between gmtime() and localtime() results it has to at least set a
>     bit in the "struct tm", but that bit may not be the full zone info).
>
>   - Even if it does work, you're stuck with only the local timezone. In
>     theory you could temporarily tweak the process's timezone, call
>     localtime(), and then tweak it back. I was never able to get that to
>     work (links below).
>
> On glibc, at least, you can access the zone fields in "struct tm" by
> compiling with _DEFAULT_SOURCE.
>
> So I think the best we could do is probably to have a feature macro like
> TM_HAS_GMTOFF, and set tm->tm_gmtoff and tm->tm_zone on platforms that
> support it. I'm not sure what we'd put in the latter, though; we don't
> actually have the timezone name at all (we just have "+0200" or whatever
> we parsed from the git object, but that would be better than nothing).
>
> That leaves other platforms still broken, but like I said, I don't think
> there's a portable solution.
>
> Here are some links to past explorations:
>
>   http://public-inbox.org/git/20160208152858.ga17...@sigill.intra.peff.net/
>
>   http://public-inbox.org/git/87vb2d37ea....@web.de/

There's a third and possibly least shitty option that isn't covered in
those threads; We could just make a pass over the strftime format
ourselves and replace %z and %Z with the timezone (as done for
DATE_ISO8601_STRICT in date.c), then hand the rest off to strftime().

I'm not going to pursue it though, Ulrich, are you maybe interested in
hacking on that?

Reply via email to