homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: email.utils.formatdate function does not handle timezones correctly.
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.1, Python 3.2, Python 3.3, Python 3.4, Python 2.7, Python 2.6
process
Status: closed Resolution: duplicate
Dependencies: Superseder: datetime-RFC2822 roundtripping
View: 665194
Assigned To: Nosy List: Vitja.Makarov, burak.arslan, izmmisha, petri.lehtinen, r.david.murray
Priority: normal Keywords:

Created on 2011年10月28日 10:26 by burak.arslan, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
test_formatdate.py burak.arslan, 2011年10月28日 10:26 small snippet to illustrate the problem
test_tz.py Vitja.Makarov, 2011年11月03日 18:38 Test timezone switch
Messages (8)
msg146551 - (view) Author: Burak Arslan (burak.arslan) Date: 2011年10月28日 10:26
There's an issue with email.utils.formatdate function, illustrated here: https://gist.github.com/1321994
for reference i'm on Europe/Istanbul timezone, which is +03:00 because of DST at the time of this writing.
I'm on stable Python 2.7.2 on gentoo linux. 
When I run the attached script, I get:
 2011年10月28日 07:56:14 -0000
 datetime.datetime(2011, 10, 28, 9, 56, 14, 945831, tzinfo=<UTC>)
when the local time is 12:56. so the second line is correct and first one is not.
let me know if you need any more information.
thanks for your attention.
msg146554 - (view) Author: Burak Arslan (burak.arslan) Date: 2011年10月28日 12:06
turns out timetuple was not passing timezone information. the correct way of converting a datetime.datetime object to a correct rfc-2822 compliant date string seems to be:
email.utils.formatdate(time.mktime(a.utctimetuple()) + 1e-6 * a.microsecond - time.timezone)
what a mess. if the above is indeed the right way to do this, is it possible to add the following function to the email.utils module?
def formatdatetime(dt_object):
 return email.utils.formatdate(time.mktime(dt_object.utctimetuple()) + 1e-6 * a.microsecond - time.timezone)
this works for datetime instances both with and without time zone information.
ps: i updated the code in the github link but not here.
msg146839 - (view) Author: Mikhail I. Izmestev (izmmisha) Date: 2011年11月02日 14:27
I have strange behavior too:
im@cgt-serv ~ $ python
Python 2.6.6 (r266:84292, Feb 28 2011, 09:01:15)
[GCC 4.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from email.Utils import formatdate
>>> import time
>>> time.strftime("%a, %d %b %Y %T %z")
'Wed, 02 Nov 2011 18:21:08 +0400'
>>> formatdate(localtime=True)
'Wed, 02 Nov 2011 18:21:28 +0300'
>>>
msg146959 - (view) Author: Vitja Makarov (Vitja.Makarov) Date: 2011年11月03日 18:38
We have the same issue in Russia (MSK timezone). It seems to be related to recent changes in timezone info.
It looks like time.timezone is calculated incorrectly.
You can test that with attached script:
$ TZ=Europe/Moscow python /tmp/test_tz.py
-10800 -14400
Both values should be the same.
msg147244 - (view) Author: Vitja Makarov (Vitja.Makarov) Date: 2011年11月07日 18:19
Perhaps it's better to calculate utc-offset for each timestamp cause we never know what is correct timezone for given time.
That could be done in C:
localtime, utc_offset = time.localtime_ex(t)
Where localtime is the same as returned by localtime() and utc_offset is set to tm.tm_gmtoff.
If tm_gmtoff isn't available on the target platform time.timezone or time.altzone will be used depending on time.daylight.
Here is simple python version, that subtracts gmtime from localtime tuple:
import time
def calculate_utc_offset(t):
 """
 Returns localtime offset for given unix-time `t`
 """
 loco = time.localtime(t)
 utc = time.gmtime(t)
 odd = cmp(loco.tm_year, utc.tm_year) or cmp(loco.tm_yday, utc.tm_yday)
 return (1440 * odd +
 60 * (loco.tm_hour - utc.tm_hour) +
 loco.tm_min - utc.tm_min))
msg147245 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011年11月07日 18:28
Unless I misunderstand your concerns, this is a duplicate of issue 665194.
msg147247 - (view) Author: Vitja Makarov (Vitja.Makarov) Date: 2011年11月07日 18:51
I'm not quite sure. The problem is email.utils.formatdate doesn't respect TZ info changes since it uses time.timezone (or time.altzone) for utc offset. 
Btw it seems that issue 665194 should fix the problem.
msg147251 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011年11月07日 19:15
formatdate doesn't know anything about datetimes, so it doesn't make any sense to me to say that it doesn't notice changes in tzinfo. That's why the fix for issue 665194 introduces a new method for formatting datetimes.
History
Date User Action Args
2022年04月11日 14:57:23adminsetgithub: 57493
2011年11月07日 19:15:22r.david.murraysetmessages: + msg147251
2011年11月07日 18:51:01Vitja.Makarovsetmessages: + msg147247
2011年11月07日 18:28:55r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg147245

superseder: datetime-RFC2822 roundtripping
resolution: duplicate
2011年11月07日 18:19:16Vitja.Makarovsetmessages: + msg147244
versions: + Python 2.6, Python 3.1, Python 3.2, Python 3.3, Python 3.4
2011年11月03日 18:38:47Vitja.Makarovsetfiles: + test_tz.py
nosy: + Vitja.Makarov
messages: + msg146959

2011年11月02日 14:27:28izmmishasetnosy: + izmmisha
messages: + msg146839
2011年10月29日 17:53:31petri.lehtinensetnosy: + petri.lehtinen
type: behavior
2011年10月28日 12:06:34burak.arslansetmessages: + msg146554
2011年10月28日 10:26:04burak.arslancreate

AltStyle によって変換されたページ (->オリジナル) /