Fix IMAP folder throwing away time zone when parsing email Date headers
Fix imapfolder.getmessageinternaldate misparsing the Date: header from emails due to a bug or surprising behaviour by email.utils.parsedate. This is because email.utils.parsedate's return value contains the unadjusted hour value from the string parsed but does not include information about the time zone in which it is specified. For example (Python 2.7.3): $ python -c "import email.utils; print email.utils.parsedate('Mon, 20 Nov 1995 19:12:08 -0500')" (1995, 11, 20, 19, 12, 8, 0, 1, -1) (the -1 is the isdst field); the -0500 time zone is completely ignored, so e.g. the same input with time "19:12:08 +0300" has the same result. When passed to time.struct_time as allowed per the parsedate documentation, this time is interpreted in GMT and thus deviates from the correct value by the timezone offset (in this example, -5 hours). I consider this a bug in email.utils.parsedate: In my opinion, since the return value of the parsetime doesn't include a timezone, it should be expressed in terms of UTC rather than in terms of the time zone from the Date header; the existence of email.utils.parsedate_tz, to which I've switched, indicates that maybe the authors were aware of this problem. Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
parent
5eef3ae473
commit
caef9a72fc
@ -7,6 +7,8 @@ ChangeLog
|
||||
WIP (add new stuff for the next release)
|
||||
========================================
|
||||
|
||||
* Honor the timezone of emails (Tobias Thierer)
|
||||
|
||||
OfflineIMAP v6.5.5-rc1 (2012-09-05)
|
||||
===================================
|
||||
|
||||
|
@ -432,16 +432,16 @@ class IMAPFolder(BaseFolder):
|
||||
(which is fine as value for append)."""
|
||||
if rtime is None:
|
||||
message = email.message_from_string(content)
|
||||
# parsedate returns a 9-tuple that can be passed directly to
|
||||
# time.mktime(); Will be None if missing or not in a valid
|
||||
# format. Note that indexes 6, 7, and 8 of the result tuple are
|
||||
# not usable.
|
||||
datetuple = email.utils.parsedate(message.get('Date'))
|
||||
dateheader = message.get('Date')
|
||||
# parsedate_tz returns a 10-tuple that can be passed to mktime_tz;
|
||||
# Will be None if missing or not in a valid format. Note that
|
||||
# indexes 6, 7, and 8 of the result tuple are not usable.
|
||||
datetuple = email.utils.parsedate_tz(dateheader)
|
||||
if datetuple is None:
|
||||
#could not determine the date, use the local time.
|
||||
return None
|
||||
#make it a real struct_time, so we have named attributes
|
||||
datetuple = time.struct_time(datetuple)
|
||||
datetuple = time.localtime(email.utils.mktime_tz(datetuple))
|
||||
else:
|
||||
#rtime is set, use that instead
|
||||
datetuple = time.localtime(rtime)
|
||||
|
Loading…
Reference in New Issue
Block a user