-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
email.utils.formatdate uses unreliable time.timezone constant #67121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The value of time.timezone may be wrong sometimes (see http://bugs.python.org/issue22752), so I think the email library should not use it: $ python3 -c "from email.utils import formatdate; print(formatdate(localtime=True))"
Mon, 24 Nov 2014 19:16:32 +0400
$ date -R
Mon, 24 Nov 2014 19:16:32 +0300 Using something from datetime module may be a better solution. |
See also bpo-665194. |
I was able to reproduce the problem on a Mac as follows: $ TZ=Europe/Moscow date "+%c %z"
Mon Nov 24 19:27:51 2014 +0300
$ TZ=Europe/Moscow python3 -c "from email.utils import formatdate; print(formatdate(localtime=True))"
Mon, 24 Nov 2014 19:28:03 +0400 |
"Using something from datetime module" works as expected: $ TZ=Europe/Moscow python3 -c "from datetime import datetime, timezone; print(datetime.now(timezone.utc).astimezone())"
2014-11-24 19:30:27.141542+03:00 |
This patch fixes the issue for me. |
email.utils.format_datetime uses datetime. formatdate wasn't touched, for backward compatibility reasons. If it has an actual bug we can fix it. If it can be converted to use datetime without sacrificing backward compatibility, that's also fine with me. Frankly I don't know enough at the moment to know if the proposed patch is correct. Alexander? |
The proposed patch will not work on platforms that don't support tm_gmtoff. A proper fix may look like this: dt = datetime.fromtimestamp(timeval, timezone.utc)
if localtime:
dt = dt.astimezone()
return format_datetime(dt, usegmt) |
Here is the updated patch based on Alexander’s suggestion. Works fine, the only difference with previous behavior is that the zero time zone is now +0000 instead of -0000. |
That's a bug (you will note that it causes a test failure in the email test suite). -0000 means "this date is in UTC, but that may or may not be the local timezone of the message". +0000 means "this date really is in the UTC timezone". utils.format_datetime uses +0000 if and only if the datetime is an aware UTC datetime. |
Thanks, I did not know that. Here is version 3. |
Yeah, only someone who has studied the RFCs would know that detail. I have no idea whether or not any email clients/processors actually *use* that distinction for anything, and I doubt there are very many humans who do :). |
v3 looks good to me. BTW, I knew that the sign of TZ 0000 was significant, but would have to look up the RFC to recall what the significance was. Thanks, David, for the explanation. |
Is there any way to write a test for this? |
This patch adds a test case for formatdate() function. Before applying issue22932_v3.patch it fails, after applying that patch it succeeds. Sorry for the delay caused by holidays. |
@mitya57: Please, combine the code changes, tests, docs into a single rietveld-compatible patch (hg diff); read devguide and http://bugs.python.org/issue13963 Make sure "review" link appears on the right near the patch. Example: |
The tests fail for me the same way both before and after the code patch: ====================================================================== Traceback (most recent call last):
File "/home/rdmurray/python/p34/Lib/test/support/__init__.py", line 1525, in inner
return func(*args, **kwds)
File "/home/rdmurray/python/p34/Lib/test/test_email/test_utils.py", line 145, in test_formatdate
self.assertEqual(string, 'Mon, 01 Dec 2014 15:00:00 -0000')
AssertionError: 'Mon, 01 Dec 2014 14:00:00 -0000' != 'Mon, 01 Dec 2014 15:00:00 -0000'
- Mon, 01 Dec 2014 14:00:00 -0000
? ^
+ Mon, 01 Dec 2014 15:00:00 -0000
? ^ ====================================================================== Traceback (most recent call last):
File "/home/rdmurray/python/p34/Lib/test/support/__init__.py", line 1525, in inner
return func(*args, **kwds)
File "/home/rdmurray/python/p34/Lib/test/test_email/test_utils.py", line 157, in test_formatdate_with_localtime
self.assertEqual(string, 'Mon, 01 Dec 2014 18:00:00 +0300')
AssertionError: 'Mon, 01 Dec 2014 18:00:00 +0400' != 'Mon, 01 Dec 2014 18:00:00 +0300'
- Mon, 01 Dec 2014 18:00:00 +0400
? ^
+ Mon, 01 Dec 2014 18:00:00 +0300
? ^ |
Can it be that you have outdated tzdata? |
Yes, that's possible. I will check. |
Upgrading the timezone data results in passed tests. Without the fix, only one of the tests fails. Is this intentional? This, however, brings up the issue that the tests may fail on the buildbots, which may also not have up to date timezone data :( |
Maybe Dmitry can come up with the "skipif" logic that will test for up-to date tzinfo and skip the test if it is not. Otherwise we can try to come up with a test case which is sufficiently far in the past. |
Now the patch works with tzdata >= 2011k, which is quite old. @david: yes, with the unpatched version only one of the tests should fail. |
New changeset fa8b76dfd138 by Robert Collins in branch '3.4': New changeset 94b43b36e464 by Robert Collins in branch '3.5': New changeset 479787100b91 by Robert Collins in branch 'default': |
Applied to 3.4 and up. Thanks for the patch! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: