Message44160
Logged In: YES
user_id=812266
The problem isn't in strftime. The problem is in gettmargs() in
timemodule.c.
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
tm.
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')
'-0500'
>>> strftime('%z', localtime())
'+0000'
This is wrong. Unsupported format specifiers do not have this
effect, for example:
>>> strftime('%L')
'%L'
>>> strftime('%L', localtime())
'%L'
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:04 | admin | link | issue762963 messages |
2007-08-23 15:28:04 | admin | create | |
|