diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index 2751d82e83..b2ea71228c 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -11,12 +11,13 @@ Usage: >>> """ +import re +import time +import calendar from django.utils.dates import MONTHS, MONTHS_3, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR from django.utils.tzinfo import LocalTimezone from django.utils.translation import ugettext as _ from django.utils.encoding import force_unicode -from calendar import isleap, monthrange -import re, time re_formatchars = re.compile(r'(? 4: - if jan1_weekday == 5 or (jan1_weekday == 6 and isleap(self.data.year-1)): + if jan1_weekday == 5 or (jan1_weekday == 6 and calendar.isleap(self.data.year-1)): week_number = 53 else: week_number = 52 else: - if isleap(self.data.year): + if calendar.isleap(self.data.year): i = 366 else: i = 365 diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index f4e49a9f52..e06d28db33 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -506,7 +506,8 @@ Available format strings: month, 2 characters. t Number of days in the given month. ``28`` to ``31`` T Time zone of this machine. ``'EST'``, ``'MDT'`` - U Not implemented. + U Seconds since the Unix Epoch + (January 1 1970 00:00:00 UTC). w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday) leading zeros. W ISO-8601 week number of year, with ``1``, ``53`` diff --git a/tests/regressiontests/dateformat/tests.py b/tests/regressiontests/dateformat/tests.py index 481e36a7dd..d649d4789c 100644 --- a/tests/regressiontests/dateformat/tests.py +++ b/tests/regressiontests/dateformat/tests.py @@ -37,7 +37,7 @@ u'th' u'31' >>> no_tz or format(my_birthday, 'T') == 'CET' True ->>> no_tz or format(my_birthday, 'U') == '300531600' +>>> no_tz or format(my_birthday, 'U') == '300315600' True >>> format(my_birthday, 'w') u'0' diff --git a/tests/regressiontests/utils/dateformat.py b/tests/regressiontests/utils/dateformat.py new file mode 100644 index 0000000000..63b8201752 --- /dev/null +++ b/tests/regressiontests/utils/dateformat.py @@ -0,0 +1,48 @@ +""" +>>> from datetime import datetime, date +>>> from django.utils.dateformat import format +>>> from django.utils.tzinfo import FixedOffset, LocalTimezone + +# date +>>> d = date(2009, 5, 16) +>>> date.fromtimestamp(int(format(d, 'U'))) == d +True + +# Naive datetime +>>> dt = datetime(2009, 5, 16, 5, 30, 30) +>>> datetime.fromtimestamp(int(format(dt, 'U'))) == dt +True + +# datetime with local tzinfo +>>> ltz = LocalTimezone(datetime.now()) +>>> dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=ltz) +>>> datetime.fromtimestamp(int(format(dt, 'U')), ltz) == dt +True +>>> datetime.fromtimestamp(int(format(dt, 'U'))) == dt.replace(tzinfo=None) +True + +# datetime with arbitrary tzinfo +>>> tz = FixedOffset(-510) +>>> ltz = LocalTimezone(datetime.now()) +>>> dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz) +>>> datetime.fromtimestamp(int(format(dt, 'U')), tz) == dt +True +>>> datetime.fromtimestamp(int(format(dt, 'U')), ltz) == dt +True +>>> datetime.fromtimestamp(int(format(dt, 'U'))) == dt.astimezone(ltz).replace(tzinfo=None) +True +>>> datetime.fromtimestamp(int(format(dt, 'U')), tz).utctimetuple() == dt.utctimetuple() +True +>>> datetime.fromtimestamp(int(format(dt, 'U')), ltz).utctimetuple() == dt.utctimetuple() +True + +# Epoch +>>> utc = FixedOffset(0) +>>> udt = datetime(1970, 1, 1, tzinfo=utc) +>>> format(udt, 'U') +u'0' +""" + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py index 485c5faa75..6d345d9afb 100644 --- a/tests/regressiontests/utils/tests.py +++ b/tests/regressiontests/utils/tests.py @@ -8,6 +8,7 @@ from django.utils import html, checksums import timesince import datastructures +import dateformat import itercompat from decorators import DecoratorFromMiddlewareTests @@ -22,6 +23,7 @@ except NameError: __test__ = { 'timesince': timesince, 'datastructures': datastructures, + 'dateformat': dateformat, 'itercompat': itercompat, }