Author quale
Date 2003-07-10.18:14:43
SpamBayes Score
Marked as misclassified
Logged In: YES 

The problem isn't in strftime. The problem is in gettmargs() in 

Python assumes that broken down time tuples are in the local 
timezone. The gettmargs() routine in timemodule.c is bugged 
on GNU libc and possibly other BSD-inspired C libraries. 
gettmargs() is supposed to take a Python broken down time 
tuple and convert it to a C struct tm. The Python time tuple 
is assumed to be in the local time zone, so the struct tm 
should be in the local timezone also. In glibc, struct tm has 
timezone fields so each struct tm knows its own timezone. 
The gettmargs() routine never fills in these extra fields so it 
always creates a struct tm in GMT. The appropriate behavior 
would be to set tm_gmtoff to the local timezone offset. My 
patch fixes gettmargs() to create struct tm's in the local 
timezone for C libraries that have the tm_gmtoff field in struct 

As to the docs issue, the Python docs say that other formats 
may be supported than the ones listed. In reality, strftime() is 
passed to the underlying C library so the format codes 
supported are whatever the C library supports. The doc 
statement "Additional directives may be supported on certain 
platforms, but only the ones listed here have a meaning 
standardized by ANSI C" is wrong, or at least not up to date. 
C99 specifies several strftime format codes that are not listed 
including %z. I think Tim Smith also mentions this in a Python 
list posting from earlier this year.

In the Python time module, the docs say strftime('format') is 
the same as strftime('format', localtime()). This is simply 
broken right now on glibc as has been reported by more than 
one person:

>>> strftime('%z')
>>> strftime('%z', localtime())

This is wrong. Unsupported format specifiers do not have this 
effect, for example:

>>> strftime('%L')
>>> strftime('%L', localtime())

This behavior is correct.

A final note on the patch: I should have looked closer at the 
timemodule.c source. It already uses the appropriate #ifdef in 
other places.  Instead of #ifdef HAVE_MKTIME my patch 
should be conditionalized #ifdef HAVE_STRUCT_TM_TM_ZONE.

It's kind of amusing to write up this long of a justification for 
what is essentially a 3 line patch.
Date User Action Args
2007-08-23 15:28:04adminlinkissue762963 messages
2007-08-23 15:28:04admincreate