[Mailman-Developers] clobber_date bug
Barry A. Warsaw
barry@zope.com
Fri, 9 Nov 2001 11:56:16 -0500
>>>>> "ES" == Eric Seppanen <eds@reric.net> writes:
ES> I just noticed a small bug. On an active list, I turned on
ES> the clobber_date setting (to apply the "resent" time to
ES> messages stored in the archives), and I noticed that it messed
ES> up the order of a bunch of messages in the archive.
ES> The reason is that clobber_date doesn't put the timezone
ES> information in the Date: field. So it looks as though the
ES> messages are dated GMT instead of GMT-6, and the messages from
ES> this morning appear after those from the afternoon.
You're right that in Mailman 2.0.x, time.ctime() is used and that
simply doesn't produce a proper RFC 2822 date.
In Mailman 2.1 however, we use email.Utils.formatdate() which is
supposed to produce a valid RFC 2822 date, homed at GMT. However, I
realized that with email-0.94, email.Utils.formatdate() is simply an
alias for rfc822.formatdate(), and the latter has not been updated to
RFC 2822. Although legal, rfc822.formatdate() produces dates with
obs-zone (obsolete zone designations, e.g. GMT) instead of the now
preferred numeric offsets from -0000.
So while MM2.1's clobber_date code should be technically correct, I
think it would be better to update email.Utils.formatdate(). Below is
what I plan on checking into CVS.
Note that this adds an optional argument `localtime' which formats the
date based on the local timezone's daylight savings time information.
For backwards compatibility, we use -0000 by default. Also, in MM2.1
I plan on leaving clobber_date to use -0000.
-Barry
-------------------- snip snip --------------------
def formatdate(timeval=None, localtime=0):
"""Returns a formatted time as specified by RFC 2822, e.g.:
Fri, 09 Nov 2001 01:08:47 -0000
Optional timeval if given is a float time as accepted by localtime() or
gmtime(). Optional localtime is a flag that when true, interprets and
returns a time relative to the local timezone instead of UTC.
"""
# Note: we cannot use strftime() because that honors the locale and RFC
# 2822 requires that day and month names be the English abbreviations.
if timeval is None:
timeval = time.time()
if localtime:
now = time.localtime(timeval)
# Calculate timezone offset, based on whether the local zone has
# daylight savings time, and whether DST is in effect.
if time.daylight and now[-1]:
offset = time.altzone
else:
offset = time.timezone
zone = '%+03d%02d' % (offset / -3600, offset % 60)
else:
now = time.gmtime(timeval)
# Timezone offset is always -0000
zone = '-0000'
return '%s, %02d %s %04d %02d:%02d:%02d %s' % (
['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][now[6]],
now[2],
['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][now[1] - 1],
now[0], now[3], now[4], now[5],
zone)