Author vstinner
Recipients vstinner
Date 2018-12-03.10:56:29
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1543834589.7.0.788709270274.issue35385@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2018-12-03 10:56:29vstinnersetrecipients: + vstinner
2018-12-03 10:56:29vstinnersetmessageid: <1543834589.7.0.788709270274.issue35385@psf.upfronthosting.co.za>
2018-12-03 10:56:29vstinnerlinkissue35385 messages
2018-12-03 10:56:29vstinnercreate