Title: time mod's timezone doesn't honor TZ var
Type: enhancement Stage:
Components: Library (Lib) Versions:
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: barry Nosy List: barry, brett.cannon, jasonrm, lemburg
Priority: low Keywords:

Created on 2001-11-30 02:09 by jasonrm, last changed 2007-09-13 23:18 by brett.cannon. This issue is now closed.

Messages (15)
msg53341 - (view) Author: Jason R. Mastaler (jasonrm) Date: 2001-11-30 02:09
Python's time module seems to get the timezone name
when it's
first imported, but it doesn't change it if the TZ
variable is later set.  On the other hand, the time of
day DOES
change accordingly.  Thus, setting TZ after the time
module is
imported results in a completely broken rfc2822 date -
time in the
new TZ, but with a bogus UTC offset and timezone
(neither the old
nor new).

Here is the problem illustrated.  You will see that
after setting TZ,
altzone, timezone, and tzname don't change, while
asctime does.

$ python2.2
Python 2.2b2 (#1, Nov 18 2001, 18:20:32) 
[GCC 2.95.3 20010315 (release) [FreeBSD]] on freebsd4
Type "help", "copyright", "credits" or "license" for
more information.
>>> import time,os
>>> print time.asctime()
Thu Nov 29 18:47:39 2001
>>> print time.altzone,time.timezone,time.tzname
21600 25200 ('MST', 'MDT')
>>> os.environ['TZ'] = "Pacific/Auckland"
>>> print time.asctime()
Fri Nov 30 14:47:52 2001
>>> print time.altzone,time.timezone,time.tzname
21600 25200 ('MST', 'MDT')

Here is an example of why this is a problem in
practice.  One of
my applications sets the TZ environment variable based
on a
"TIMEZONE" setting in the user's configuration file. 
It later uses
the `email' module to create a "Date:" header for
outgoing mail
messages.  Because of this bug, the resulting "Date:"
is bogus.

$ python2.2
Python 2.2b2 (#1, Nov 18 2001, 18:20:32) 
[GCC 2.95.3 20010315 (release) [FreeBSD]] on freebsd4
Type "help", "copyright", "credits" or "license" for
more information.
>>> import email,os
>>> print email.Utils.formatdate(localtime=1)
Thu, 29 Nov 2001 18:52:34 -0700
>>> os.environ['TZ'] = "Pacific/Auckland"
>>> print email.Utils.formatdate(localtime=1)
Fri, 30 Nov 2001 14:52:41 -0600

The `-0600' should be `+1300', and `-0600' isn't
correct even for the original timezone!

You might say: "Work around this by setting TZ before
the time
module is first imported." -- No, that is too fragile,
and too difficult
to do with complex applications.  Many other modules in
import time, etc.  I suggest instead that the TZ
variable be consulted each time the timezone is
msg53342 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2001-11-30 19:01
Logged In: YES 

The time module is a very thin layer on top of the C lib time APIs. There's nothing much Python can do about 
errors in those APIs, e.g. not recognizing changes to TZ.

Also note that the tzset() API which inits the time APIs w/r to the TZ environment variable is only called at time 
module import time. To expose the dynamic changes you are looking for, it would have to call tzset() prior to all 
calls to asctime() et al. -- much too time consuming !
msg53343 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2001-11-30 20:11
Logged In: YES 

Perhaps we should expose tzset() to Python?  We'd also have
to reset timezone, altzone, daylight, and tzname in the
module after calling tzset().

It's a bit of work, and adds a feature so it can't go into
Python 2.2, but if you think this is a viable approach,
re-assign this bug to me and I'll deal with it for Python 2.3.
msg53344 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2001-11-30 20:53
Logged In: YES 

I don't know whether this is such a good idea -- after all it's fairly easy to manage timezones in the application 
rather than trying to fiddle the C libs routines into producing the output you intend. Also note that tzset() is *not* 
thread safe.

BTW, Jason, you may want to have a look at mxDateTime -- perhaps it already has what you are looking for.
msg53345 - (view) Author: Jason R. Mastaler (jasonrm) Date: 2001-12-03 21:56
Logged In: YES 

I'm fairly ignorant of the gory details behind
the scenes of the time module, but I still contend
this is buggy behavior.  That is, setting
os.environ['TZ'] in the application totally
breaks higher level methods such as 

Barry had a suggestion which Mark doesn't think
is a good idea.  Mark, are you sure there isn't 
anything that can be done?  If think that if you 
disregard this issue, it will come back to haunt
the Python community.

With regards to your suggestion of mxDateTime:
I really can't consider this as I don't want to
rely on any external modules or packages.  
One of my application's strengths is that it 
"just works" out of the box with Python, so it's
very easy to install.  I'd like to keep it that
way unless it's absolutely necessary to do otherwise.
msg53346 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2001-12-04 09:36
Logged In: YES 

Jason, as I already mentioned in my other reply, exposing tzset() to Python would cause more trouble than do any 
good because of the side-effects it has.

Rather then provide ways to write buggy code in Python, I suggest to look into solving the problem you seem to 
have using the available tools, e.g. mxDateTime runs on many different platforms and integrates nicely with 

If the email package is the only one you need fixed, I suggest to write a small helper or patch which implements 
the needed modifications for this package. BTW, what are you exact requirements ?
msg53347 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2001-12-04 15:03
Logged In: YES 

OT, but what about adding mxDateTime to core Python <2.3 wink>?
msg53348 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2001-12-04 15:04
Logged In: YES 

BTW, one way to possibly handle this would be to add
something to time module that created a "timezone object",
encapsulating daylight, timezone, and altzone for arbitrary
timezones.  Then date producing code like
email.Utils.formatdate() could take optional timezone
objects to produce dates relative to the given zone.
msg53349 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2001-12-04 15:48
Logged In: YES 

Well, this may sound easy, but once you get into timezones things start to become one big can of worms, e.g. 
just have a look at how daylight savings time is handled in different countries of the world or how time zone names 
sometimes map to multiple different zones. 

OTOH, numeric timezones are easy to handle and all that is needed is some simple code to convert a ticks value 
plus an offset to a nice ISO string representation an vice-versa. That should be easy to add to the time module...

About adding mxDateTime to the core: I suppose it's simply too big. Also, I have a slightly different way of 
maintaining the mx tools than what is considered the Python way -- I usually happily add new features and 
modules without much fuzz; wouldn't want to have to write a PEP to enhance my own stuff ;-)

As compromise, I could add some ISO date/time parsing and formatting code from mxDateTime to Python 2.3.
msg53350 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2001-12-04 16:11
Logged In: YES 

Rightt, all I was thinking about was an object/function to
encapsulate the numeric timezone values, daylight, timezone,
and altzone, without sucking in all fo the timezone names
and abbreviations.

As for mxDateTime, yeah putting that into Python would
probably mean some compromise on the projmgt side of things.
 OTOH, it would be damn handy! :)

Oh well, plenty of time to think about this for Python 2.3!
msg53351 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2001-12-05 09:37
Logged In: YES 

Agreed. Let's continue to talk about this after Python 2.2 is out.
msg53352 - (view) Author: Jason R. Mastaler (jasonrm) Date: 2001-12-05 23:58
Logged In: YES 


To answer your question from a couple days ago,
my exact requirements are:  The ability to produce
an rfc2822 compliant "Date" string that corresponds
to the current value of 'TZ' in the environment.  
I'm currently using email.Utils.formatdate() to 
produce the Date, but this breaks as soon as I set 
'TZ' within my application.  Setting 'TZ' from 
within Python is necessary.  I don't currently
know of a way to get around this problem as the
breakage is in the lower level time module.

Again, mxDateTime is NOT an option.  Whether it 
integrates nicely with Python and runs on many 
platforms is not relevant.  I'm sure both of these 
facts are true, but I don't want my application to 
depend on any external packages.  This complicates 
the installation procedure unnecessarily.
msg53353 - (view) Author: Jason R. Mastaler (jasonrm) Date: 2001-12-06 00:34
Logged In: YES 

Marc-André, I apologize for previously misspelling your 
name a bunch of times.  Oops.
msg53354 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2002-09-05 07:37
Logged In: YES 

Passed on top Barry. I won't have time for this in the next
few weeks.
msg55900 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2007-09-13 23:18
time.tzset() was added in Python 2.3.  Closing as fixed.
Date User Action Args
2007-09-13 23:18:45brett.cannonsetstatus: open -> closed
nosy: + brett.cannon
resolution: fixed
messages: + msg55900
2001-11-30 02:09:14jasonrmcreate