This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Python configure fails to detect tzname on platforms that have it.
Type: behavior Stage:
Components: Versions: Python 3.7, Python 3.6, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: belopolsky, izbyshev, lemburg, vstinner
Priority: normal Keywords:

Created on 2016-09-12 19:33 by belopolsky, last changed 2022-04-11 14:58 by admin.

Messages (9)
msg276098 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-09-12 19:33
After running ./configure on Linux or MacOS X, check the generated pyconfig.h header:

$ grep TZNAME pyconfig.h
/* #undef HAVE_DECL_TZNAME */
/* #undef HAVE_TZNAME */

However, tzname exists and is declared in time.h on Linux and MacOS X as can be seen by compiling and running the following simple program:

$ cat tzname.c
#include <time.h>
#include <stdio.h>

int main() {
    tzset();
    printf("%s/%s\n", tzname[0], tzname[1]);
}
$ clang tzname.c -o tzname
$ ./tzname
EST/EDT

Note that tzname is mandated by the recent editions of POSIX <http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html>, so I am not sure whether we need to check for it in configure.
msg276111 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2016-09-12 20:20
Looking at the autoconf documentation, HAVE_TZNAME is only set iff struct tm does not have a tm_zone member *and* the external array tzname is found:

https://www.gnu.org/software/autoconf/manual/autoconf-2.64/html_node/Particular-Structures.html

If the struct tm does have a tm_zone member (which it does on Linux), the check for tzname is not even run.
msg276112 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-09-12 20:24
> HAVE_TZNAME is only set iff struct tm does not have a tm_zone member ...

I've figured that much from reading the generated configure script, but thanks for the pointer to the documentation.
msg276117 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2016-09-12 20:55
If you want to separately check for the definition of tzname,
I guess you have to add a AC_DEFINE() section specifically
for tzname.
msg276121 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-09-12 21:04
The real issue is that when setting the tzname tuple in the time module, we use a guess based on the value of tm_zone probed in June and January.  I am not sure whether this is wise.  Shouldn't we just use C tzname is it is available?
msg276122 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2016-09-12 21:16
> The real issue is that when setting the tzname tuple in the time module, we use a guess based on the value of tm_zone probed in June and January.  I am not sure whether this is wise.  Shouldn't we just use C tzname is it is available?

I don't think tzname is really all that useful. In mxDateTime,
I use strftime() with "%Z" to obtain the timezone string for
a given local time.

tzname tries to identify non-DST vs. DST of the local time zone,
but this may fail for cases where a country switches DST settings
in a particular year as it happened in Russia:

https://www.timeanddate.com/time/zone/russia/moscow
msg276123 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-09-12 21:31
> I don't think tzname is really all that useful.

I agree. More so after issue 25283 (Make tm_gmtoff and tm_zone available on all platforms).  That's why I don't see why the time module need to set tzname to anything other than what the C library does.

Interestingly, glibc may even change tzname[0] as a side-effect of calling  localtime:

(on Linux)
$ cat lt.c
#include <time.h>
#include <stdio.h>


int main() {
  struct tm tm = {0, 0, 0, 1, 1, -100};
  time_t t;
  t = mktime(&tm);
  localtime(&t);
  printf("%s/%s  %d %d\n", tzname[0], tzname[1], timezone, daylight);
  t = 0;
  localtime(&t);
  printf("%s/%s  %d %d\n", tzname[0], tzname[1], timezone, daylight);
}

$ gcc lt.c -o lt
$ ./lt
LMT/EDT  18000 1
EST/EDT  18000 1

I think that's a bug in glibc because it makes no sense to change tzname[0] while not updating timezone.
msg332394 - (view) Author: Alexey Izbyshev (izbyshev) * (Python triager) Date: 2018-12-23 19:23
The resolution of this [1] glibc bug report effectively says that the use of global variables tzname, timezone and daylight is not supported by glibc unless a POSIX-style TZ setting is used (which is probably never in real world).

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=23859
msg333025 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-01-04 23:50
See also bpo-35385.
History
Date User Action Args
2022-04-11 14:58:36adminsetgithub: 72295
2019-01-04 23:50:18vstinnersetmessages: + msg333025
2018-12-23 19:23:00izbyshevsetnosy: + izbyshev
messages: + msg332394
2016-09-12 21:31:58belopolskysetmessages: + msg276123
2016-09-12 21:16:01lemburgsetmessages: + msg276122
2016-09-12 21:04:00belopolskysetmessages: + msg276121
2016-09-12 20:55:14lemburgsetmessages: + msg276117
2016-09-12 20:24:22belopolskysetmessages: + msg276112
2016-09-12 20:20:33lemburgsetmessages: + msg276111
2016-09-12 19:34:49belopolskysetnosy: + lemburg, vstinner
2016-09-12 19:33:55belopolskycreate