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: time module: why not using tzname from the glibc?
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: belopolsky, izbyshev, p-ganssle, vstinner
Priority: normal Keywords:

Created on 2018-12-03 10:56 by vstinner, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg330932 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2018-12-03 10:56
Currently, the time module uses tm_zone and tm_gmtoff of struct tm with localtime_r() to get the timezone (name and offset) on my Fedora 29. But it seems like glibc provides "tzname", "daylight" and "timezone" variables. Why not using them?
 
Python also provides "altzone", I'm not sure how to get this value from the glibc. See also the documentation:

https://docs.python.org/dev/library/time.html#timezone-constants


It's not a bug, it's more a question :-)


It seems like the configure script always undefine HAVE_DECL_TZNAME:
---
/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
   */
#undef HAVE_DECL_TZNAME
---


Example of C program:
---
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    putenv("TZ=UTC");
    tzset();
    printf("tzname = {%s, %s}\n", tzname[0], tzname[1]);
    exit(EXIT_SUCCESS);
}
---


Output on Fedora 29, glibc 2.28:
---
tzname = {UTC, UTC}
---


Note: tzname is not always defined by <time.h>:
---
/* Defined in localtime.c.  */
extern char *__tzname[2];	/* Current timezone names.  */
extern int __daylight;		/* If daylight-saving time is ever in use.  */
extern long int __timezone;	/* Seconds west of UTC.  */


#ifdef	__USE_POSIX
/* Same as above.  */
extern char *tzname[2];

/* Set time conversion information from the TZ environment variable.
   If TZ is not defined, a locale-dependent default is used.  */
extern void tzset (void) __THROW;
#endif

#if defined __USE_MISC || defined __USE_XOPEN
extern int daylight;
extern long int timezone;
#endif
---


configure should try to tzname is available no?


For HAVE_WORKING_TZSET, configure contains a C program which uses HAVE_TZNAME. Extract:
---
#if HAVE_TZNAME
extern char *tzname[];
#endif
...
	putenv("TZ=UTC+0");
	tzset();
	if (localtime(&groundhogday)->tm_hour != 0)
	    exit(1);
#if HAVE_TZNAME
	/* For UTC, tzname[1] is sometimes "", sometimes "   " */
	if (strcmp(tzname[0], "UTC") ||
		(tzname[1][0] != 0 && tzname[1][0] != ' '))
	    exit(1);
#endif
---


I don't understand the test on the TZ=UTC+0 timezone: I get tzname[0]="UTC" and tzname[1]="UTC" which fails the test...


In Python 2.7, there is:
---
    /* This code moved from inittime wholesale to allow calling it from
    time_tzset. In the future, some parts of it can be moved back
    (for platforms that don't HAVE_WORKING_TZSET, when we know what they
    are), and the extraneous calls to tzset(3) should be removed.
    I haven't done this yet, as I don't want to change this code as
    little as possible when introducing the time.tzset and time.tzsetwall
    methods. This should simply be a method of doing the following once,
    at the top of this function and removing the call to tzset() from
    time_tzset():

        #ifdef HAVE_TZSET
        tzset()
        #endif

    And I'm lazy and hate C so nyer.
     */

#if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
---

The glibc is explicitly excluded from platforms which support "tzname". The "!defined(__GLIBC__)" test is quite old...

commit ea424e19f152638260c91d5fd6a805a288c931d2
Author: Guido van Rossum <guido@python.org>
Date:   Fri Apr 23 20:59:05 1999 +0000

    Apparently __GNU_LIBRARY__ is defined for glibc as well as for libc5.
    The test really wanted to distinguish between the two.  So now we test
    for __GLIBC__ instead.  I have confirmed that this works for glibc and
    I have an email from Christian Tanzer confirming that it works for
    libc5, so it should be fine.
msg330933 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2018-12-03 10:58
Ah, context of this question: I modified get_gmtoff() in bpo-35373 to fix compiler warnings :-) (see my first commit 503ce5c482cb267b0770bc46c315d5cf822bdca9)
msg330944 - (view) Author: Alexey Izbyshev (izbyshev) * (Python triager) Date: 2018-12-03 13:03
See #28108 and https://sourceware.org/bugzilla/show_bug.cgi?id=23859 (for msg276123).
msg333026 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-01-04 23:50
See also bpo-28108.
msg345447 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-06-13 01:13
This issue isn't really a bug. The current code just works. I close the issue.
History
Date User Action Args
2022-04-11 14:59:08adminsetgithub: 79566
2019-06-13 01:13:56vstinnersetstatus: open -> closed
resolution: not a bug
messages: + msg345447

stage: resolved
2019-01-04 23:50:20vstinnersetmessages: + msg333026
2018-12-03 16:45:16p-gansslesetnosy: + p-ganssle
2018-12-03 13:03:46izbyshevsetnosy: + izbyshev
messages: + msg330944
2018-12-03 10:58:34vstinnersetmessages: + msg330933
2018-12-03 10:57:01vstinnersetnosy: + belopolsky
2018-12-03 10:56:29vstinnercreate