This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: localtime and TZ


On 10/30/2010 8:43 AM, Ken Brown wrote:
On 10/29/2010 7:17 PM, Ken Brown wrote:
On 10/29/2010 6:16 PM, Eric Blake wrote:
On 10/29/2010 04:11 PM, Ken Brown wrote:

Thanks, Eric. I didn't know about any of this. (I was using a modification of a configure test from the emacs sources.)

Probably worth pointing it out to the emacs upstream, then :)


But I get the same behavior with the following revised test case:

#include<time.h>
#include<stdio.h>

int
main (void)
{
     time_t now = time ((time_t *) 0);
     printf ("TZ is initially unset; hour = %d\n", localtime (&now)->tm_hour);
     putenv ("TZ=GMT0");
     printf ("TZ=GMT0; hour = %d\n", localtime (&now)->tm_hour);
     unsetenv("TZ");
     printf ("TZ unset; hour = %d\n", localtime (&now)->tm_hour);
     putenv ("TZ=PST8");
     printf ("TZ=PST8; hour = %d\n", localtime (&now)->tm_hour);
     unsetenv("TZ");
     printf ("TZ unset again; hour = %d\n", localtime (&now)->tm_hour);
}

So the question remains whether this difference between Cygwin and Linux is a bug or by design.

Apparently by design. POSIX requires:


http://www.opengroup.org/onlinepubs/9699919799/functions/localtime.html

Local timezone information is used as though localtime() calls tzset().

http://www.opengroup.org/onlinepubs/9699919799/functions/tzset.html

The tzset() function shall use the value of the environment variable TZ
to set time conversion information used by ctime , localtime , mktime ,
and strftime . If TZ is absent from the environment,
implementation-defined default timezone information shall be used.

Wouldn't you interpret this as meaning that the implementation-defined default timezone information should be the same every time localtime is called with TZ unset? If not, what should a program do to get the "standard" default timezone information that it would get if TZ had never been set in the first place?

I've looked at Cygwin's localtime.cc, and the behavior I'm complaining about is caused by the following code at the beginning of tzset:

const char * name = getenv("TZ");

	if (name == NULL) {
		if (!lcl_is_set)
			tzsetwall();
		goto out;
	}

So getting rid of 'if (!lcl_is_set)' would solve the problem.  But this
would be inefficient, because it would mean that tzsetwall gets called
every time tzset is called if TZ is never set.  To get around that, one
could have tzsetwall set TZ.

It seems that tzset and tzsetwall used to behave the way I'm proposing
before the following two changes were made:

2007-12-11 Corinna Vinschen<corinna@vinschen.de>

	* localtime.cc (tzset): Call tzsetwall only if it hasn't been
	called before.

2007-08-01 Corinna Vinschen<corinna@vinschen.de>

* localtime.cc (tzsetwall): Don't set TZ.

I've just found the reason for the 2007-08-01 change:


http://www.cygwin.com/ml/cygwin/2007-08/msg00041.html

So I don't know what should be done.

Ken

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]