Code

Ticket #10825: 10825.diff

File 10825.diff, 4.5 KB (added by mir, 5 years ago)

patch inluding fix of testcases, replaces older patch

Line 
1diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py
2index 2751d82..f5edf42 100644
3--- a/django/utils/dateformat.py
4+++ b/django/utils/dateformat.py
5@@ -16,7 +16,9 @@ from django.utils.tzinfo import LocalTimezone
6 from django.utils.translation import ugettext as _
7 from django.utils.encoding import force_unicode
8 from calendar import isleap, monthrange
9-import re, time
10+import re
11+from calendar import timegm
12+from time import mktime
13 
14 re_formatchars = re.compile(r'(?<!\\)([aAbBdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])')
15 re_escaped = re.compile(r'\\(.)')
16@@ -199,8 +201,10 @@ class DateFormat(TimeFormat):
17 
18     def U(self):
19         "Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
20-        off = self.timezone and self.timezone.utcoffset(self.data) or 0
21-        return int(time.mktime(self.data.timetuple())) + off.seconds * 60
22+        if getattr(self.data, 'tzinfo', None):
23+            return int(timegm(self.data.utctimetuple()))
24+        else:
25+            return int(mktime(self.data.timetuple()))
26 
27     def w(self):
28         "Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)"
29diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
30index f4e49a9..e06d28d 100644
31--- a/docs/ref/templates/builtins.txt
32+++ b/docs/ref/templates/builtins.txt
33@@ -506,7 +506,8 @@ Available format strings:
34                       month, 2 characters.
35     t                 Number of days in the given month.        ``28`` to ``31``
36     T                 Time zone of this machine.                ``'EST'``, ``'MDT'``
37-    U                 Not implemented.
38+    U                 Seconds since the Unix Epoch
39+                      (January 1 1970 00:00:00 UTC).
40     w                 Day of the week, digits without           ``'0'`` (Sunday) to ``'6'`` (Saturday)
41                       leading zeros.
42     W                 ISO-8601 week number of year, with        ``1``, ``53``
43diff --git a/tests/regressiontests/dateformat/tests.py b/tests/regressiontests/dateformat/tests.py
44index 481e36a..d649d47 100644
45--- a/tests/regressiontests/dateformat/tests.py
46+++ b/tests/regressiontests/dateformat/tests.py
47@@ -37,7 +37,7 @@ u'th'
48 u'31'
49 >>> no_tz or format(my_birthday, 'T') == 'CET'
50 True
51->>> no_tz or format(my_birthday, 'U') == '300531600'
52+>>> no_tz or format(my_birthday, 'U') == '300315600'
53 True
54 >>> format(my_birthday, 'w')
55 u'0'
56diff --git a/tests/regressiontests/utils/dateformat.py b/tests/regressiontests/utils/dateformat.py
57new file mode 100644
58index 0000000..63b8201
59--- /dev/null
60+++ b/tests/regressiontests/utils/dateformat.py
61@@ -0,0 +1,48 @@
62+"""
63+>>> from datetime import datetime, date
64+>>> from django.utils.dateformat import format
65+>>> from django.utils.tzinfo import FixedOffset, LocalTimezone
66+
67+# date
68+>>> d = date(2009, 5, 16)
69+>>> date.fromtimestamp(int(format(d, 'U'))) == d
70+True
71+
72+# Naive datetime
73+>>> dt = datetime(2009, 5, 16, 5, 30, 30)
74+>>> datetime.fromtimestamp(int(format(dt, 'U'))) == dt
75+True
76+
77+# datetime with local tzinfo
78+>>> ltz = LocalTimezone(datetime.now())
79+>>> dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=ltz)
80+>>> datetime.fromtimestamp(int(format(dt, 'U')), ltz) == dt
81+True
82+>>> datetime.fromtimestamp(int(format(dt, 'U'))) == dt.replace(tzinfo=None)
83+True
84+
85+# datetime with arbitrary tzinfo
86+>>> tz = FixedOffset(-510)
87+>>> ltz = LocalTimezone(datetime.now())
88+>>> dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz)
89+>>> datetime.fromtimestamp(int(format(dt, 'U')), tz) == dt
90+True
91+>>> datetime.fromtimestamp(int(format(dt, 'U')), ltz) == dt
92+True
93+>>> datetime.fromtimestamp(int(format(dt, 'U'))) == dt.astimezone(ltz).replace(tzinfo=None)
94+True
95+>>> datetime.fromtimestamp(int(format(dt, 'U')), tz).utctimetuple() == dt.utctimetuple()
96+True
97+>>> datetime.fromtimestamp(int(format(dt, 'U')), ltz).utctimetuple() == dt.utctimetuple()
98+True
99+
100+# Epoch
101+>>> utc = FixedOffset(0)
102+>>> udt = datetime(1970, 1, 1, tzinfo=utc)
103+>>> format(udt, 'U')
104+u'0'
105+"""
106+
107+if __name__ == "__main__":
108+    import doctest
109+    doctest.testmod()
110diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py
111index 485c5fa..6d345d9 100644
112--- a/tests/regressiontests/utils/tests.py
113+++ b/tests/regressiontests/utils/tests.py
114@@ -8,6 +8,7 @@ from django.utils import html, checksums
115 
116 import timesince
117 import datastructures
118+import dateformat
119 import itercompat
120 from decorators import DecoratorFromMiddlewareTests
121 
122@@ -22,6 +23,7 @@ except NameError:
123 __test__ = {
124     'timesince': timesince,
125     'datastructures': datastructures,
126+    'dateformat': dateformat,
127     'itercompat': itercompat,
128 }
129