]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #22932: Fix timezones in email.utils.formatdate.
authorRobert Collins <rbtcollins@hp.com>
Fri, 31 Jul 2015 20:18:22 +0000 (08:18 +1200)
committerRobert Collins <rbtcollins@hp.com>
Fri, 31 Jul 2015 20:18:22 +0000 (08:18 +1200)
Patch from Dmitry Shachnev.

Lib/email/utils.py
Lib/test/test_email/test_utils.py
Misc/ACKS
Misc/NEWS

index 317fdfa3b678ce822bc1886ac2a0a57a940502c2..5080d81909bb900a13b57a4af3c997227a126dbd 100644 (file)
@@ -155,30 +155,14 @@ def formatdate(timeval=None, localtime=False, usegmt=False):
     # 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
-        hours, minutes = divmod(abs(offset), 3600)
-        # Remember offset is in seconds west of UTC, but the timezone is in
-        # minutes east of UTC, so the signs differ.
-        if offset > 0:
-            sign = '-'
-        else:
-            sign = '+'
-        zone = '%s%02d%02d' % (sign, hours, minutes // 60)
+    if localtime or usegmt:
+        dt = datetime.datetime.fromtimestamp(timeval, datetime.timezone.utc)
     else:
-        now = time.gmtime(timeval)
-        # Timezone offset is always -0000
-        if usegmt:
-            zone = 'GMT'
-        else:
-            zone = '-0000'
-    return _format_timetuple_and_zone(now, zone)
+        dt = datetime.datetime.utcfromtimestamp(timeval)
+    if localtime:
+        dt = dt.astimezone()
+        usegmt = False
+    return format_datetime(dt, usegmt)
 
 def format_datetime(dt, usegmt=False):
     """Turn a datetime into a date string as specified in RFC 2822.
index 4abdc04f344ffaa085bb6a4dc648497fd944da61..1e9cd63e520a2a2eaeea8147aa6044b7e578f6d8 100644 (file)
@@ -136,5 +136,25 @@ class LocaltimeTests(unittest.TestCase):
         t1 = utils.localtime(t0)
         self.assertEqual(t1.tzname(), 'EET')
 
+class FormatDateTests(unittest.TestCase):
+
+    @test.support.run_with_tz('Europe/Minsk')
+    def test_formatdate(self):
+        timeval = time.mktime((2011, 12, 1, 18, 0, 0, 4, 335, 0))
+        string = utils.formatdate(timeval, localtime=False, usegmt=False)
+        self.assertEqual(string, 'Thu, 01 Dec 2011 15:00:00 -0000')
+        string = utils.formatdate(timeval, localtime=False, usegmt=True)
+        self.assertEqual(string, 'Thu, 01 Dec 2011 15:00:00 GMT')
+
+    @test.support.run_with_tz('Europe/Minsk')
+    def test_formatdate_with_localtime(self):
+        timeval = time.mktime((2011, 1, 1, 18, 0, 0, 6, 1, 0))
+        string = utils.formatdate(timeval, localtime=True)
+        self.assertEqual(string, 'Sat, 01 Jan 2011 18:00:00 +0200')
+        # Minsk moved from +0200 (with DST) to +0300 (without DST) in 2011
+        timeval = time.mktime((2011, 12, 1, 18, 0, 0, 4, 335, 0))
+        string = utils.formatdate(timeval, localtime=True)
+        self.assertEqual(string, 'Thu, 01 Dec 2011 18:00:00 +0300')
+
 if __name__ == '__main__':
     unittest.main()
index de33df13785dfa5cbc436aa2462d19073b6836a0..cc557b311bf1aa6bc763eca2a46bf31c60abe224 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1247,6 +1247,7 @@ Jerry Seutter
 Pete Sevander
 Denis Severson
 Ian Seyer
+Dmitry Shachnev
 Daniel Shahaf
 Ha Shao
 Mark Shannon
index 6798182a9900f3ee13b880151e25353cef4e1d08..1aa2ea3e96cdb702892180d87d555a8e086c96f7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -66,6 +66,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #22932: Fix timezones in email.utils.formatdate.
+  Patch from Dmitry Shachnev.
+
 - Issue #23779: imaplib raises TypeError if authenticator tries to abort.
   Patch from Craig Holmquist.