diff --git a/django/contrib/humanize/tests.py b/django/contrib/humanize/tests.py index f41c948305..7997986370 100644 --- a/django/contrib/humanize/tests.py +++ b/django/contrib/humanize/tests.py @@ -14,10 +14,9 @@ from django.template import Template, Context, defaultfilters from django.test import TestCase from django.test.utils import override_settings from django.utils.html import escape -from django.utils.timezone import utc +from django.utils.timezone import utc, get_fixed_timezone from django.utils import translation from django.utils.translation import ugettext as _ -from django.utils import tzinfo from i18n import TransRealMixin @@ -153,8 +152,8 @@ class HumanizeTests(TransRealMixin, TestCase): def test_naturalday_tz(self): today = datetime.date.today() - tz_one = tzinfo.FixedOffset(datetime.timedelta(hours=-12)) - tz_two = tzinfo.FixedOffset(datetime.timedelta(hours=12)) + tz_one = get_fixed_timezone(-720) + tz_two = get_fixed_timezone(720) # Can be today or yesterday date_one = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_one) diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py index cec204dc92..9878070d4b 100644 --- a/django/contrib/syndication/views.py +++ b/django/contrib/syndication/views.py @@ -7,12 +7,12 @@ from django.contrib.sites.models import get_current_site from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist from django.http import HttpResponse, Http404 from django.template import loader, TemplateDoesNotExist, RequestContext -from django.utils import feedgenerator, tzinfo +from django.utils import feedgenerator from django.utils.encoding import force_text, iri_to_uri, smart_text from django.utils.html import escape from django.utils.http import http_date from django.utils import six -from django.utils.timezone import is_naive +from django.utils.timezone import get_default_timezone, is_naive, make_aware def add_domain(domain, url, secure=False): @@ -186,15 +186,15 @@ class Feed(object): else: author_email = author_link = None + tz = get_default_timezone() + pubdate = self.__get_dynamic_attr('item_pubdate', item) if pubdate and is_naive(pubdate): - ltz = tzinfo.LocalTimezone(pubdate) - pubdate = pubdate.replace(tzinfo=ltz) + pubdate = make_aware(pubdate, tz) updateddate = self.__get_dynamic_attr('item_updateddate', item) if updateddate and is_naive(updateddate): - ltz = tzinfo.LocalTimezone(updateddate) - updateddate = updateddate.replace(tzinfo=ltz) + updateddate = make_aware(updateddate, tz) feed.add_item( title = title, diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index fbf299631b..85eb975f84 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -18,11 +18,10 @@ import calendar import datetime from django.utils.dates import MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR -from django.utils.tzinfo import LocalTimezone from django.utils.translation import ugettext as _ from django.utils.encoding import force_text from django.utils import six -from django.utils.timezone import is_aware, is_naive +from django.utils.timezone import get_default_timezone, is_aware, is_naive re_formatchars = re.compile(r'(?\d{4})-(?P\d{1,2})-(?P\d{1,2})$' @@ -27,6 +27,7 @@ datetime_re = re.compile( r'(?PZ|[+-]\d{2}:?\d{2})?$' ) + def parse_date(value): """Parses a string and return a datetime.date. @@ -59,7 +60,7 @@ def parse_datetime(value): """Parses a string and return a datetime.datetime. This function supports time zone offsets. When the input contains one, - the output uses an instance of FixedOffset as tzinfo. + the output uses a timezone with a fixed offset from UTC. Raises ValueError if the input is well formatted but not a valid datetime. Returns None if the input isn't well formatted. @@ -76,7 +77,7 @@ def parse_datetime(value): offset = 60 * int(tzinfo[1:3]) + int(tzinfo[-2:]) if tzinfo[0] == '-': offset = -offset - tzinfo = FixedOffset(offset) + tzinfo = get_fixed_timezone(offset) kw = dict((k, int(v)) for k, v in six.iteritems(kw) if v is not None) kw['tzinfo'] = tzinfo return datetime.datetime(**kw) diff --git a/tests/model_regress/tests.py b/tests/model_regress/tests.py index f84a40b05b..a0293975aa 100644 --- a/tests/model_regress/tests.py +++ b/tests/model_regress/tests.py @@ -8,7 +8,7 @@ import unittest from django.core.exceptions import ValidationError from django.test import TestCase, skipUnlessDBFeature from django.utils import six -from django.utils import tzinfo +from django.utils.timezone import get_fixed_timezone from django.db import connection, router from django.db.models.sql import InsertQuery @@ -189,8 +189,8 @@ class ModelTests(TestCase): # Regression test for #10443. # The idea is that all these creations and saving should work without # crashing. It's not rocket science. - dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(600)) - dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=tzinfo.FixedOffset(600)) + dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=get_fixed_timezone(600)) + dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=get_fixed_timezone(600)) obj = Article.objects.create( headline="A headline", pub_date=dt1, article_text="foo" ) diff --git a/tests/syndication/feeds.py b/tests/syndication/feeds.py index f8ffb4b2e6..2097cb62ad 100644 --- a/tests/syndication/feeds.py +++ b/tests/syndication/feeds.py @@ -2,7 +2,8 @@ from __future__ import unicode_literals from django.contrib.syndication import views from django.core.exceptions import ObjectDoesNotExist -from django.utils import feedgenerator, tzinfo +from django.utils import feedgenerator +from django.utils.timezone import get_fixed_timezone from .models import Article, Entry @@ -140,7 +141,7 @@ class TZAwareDatesFeed(TestAtomFeed): # Provide a weird offset so that the test can know it's getting this # specific offset and not accidentally getting on from # settings.TIME_ZONE. - return item.published.replace(tzinfo=tzinfo.FixedOffset(42)) + return item.published.replace(tzinfo=get_fixed_timezone(42)) class TestFeedUrlFeed(TestAtomFeed): diff --git a/tests/syndication/tests.py b/tests/syndication/tests.py index 79004aa8b9..92b844fc25 100644 --- a/tests/syndication/tests.py +++ b/tests/syndication/tests.py @@ -1,19 +1,36 @@ from __future__ import unicode_literals +import datetime from xml.dom import minidom +try: + import pytz +except ImportError: + pytz = None + from django.contrib.syndication import views from django.core.exceptions import ImproperlyConfigured from django.test import TestCase -from django.utils import tzinfo from django.utils.feedgenerator import rfc2822_date, rfc3339_date +from django.utils import timezone from .models import Entry +TZ = timezone.get_default_timezone() + + class FeedTestCase(TestCase): fixtures = ['feeddata.json'] + def setUp(self): + # Django cannot deal with very old dates when pytz isn't installed. + if pytz is None: + old_entry = Entry.objects.get(pk=1) + old_entry.updated = datetime.datetime(1980, 1, 1, 12, 30) + old_entry.published = datetime.datetime(1986, 9, 25, 20, 15, 00) + old_entry.save() + def assertChildNodes(self, elem, expected): actual = set(n.nodeName for n in elem.childNodes) expected = set(expected) @@ -59,8 +76,7 @@ class SyndicationFeedTest(FeedTestCase): # Find the last build date d = Entry.objects.latest('published').published - ltz = tzinfo.LocalTimezone(d) - last_build_date = rfc2822_date(d.replace(tzinfo=ltz)) + last_build_date = rfc2822_date(timezone.make_aware(d, TZ)) self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category']) self.assertChildNodeContent(chan, { @@ -89,8 +105,7 @@ class SyndicationFeedTest(FeedTestCase): # Find the pubdate of the first feed item d = Entry.objects.get(pk=1).published - ltz = tzinfo.LocalTimezone(d) - pub_date = rfc2822_date(d.replace(tzinfo=ltz)) + pub_date = rfc2822_date(timezone.make_aware(d, TZ)) items = chan.getElementsByTagName('item') self.assertEqual(len(items), Entry.objects.count()) @@ -242,8 +257,7 @@ class SyndicationFeedTest(FeedTestCase): updated = feed.getElementsByTagName('updated')[0].firstChild.wholeText d = Entry.objects.latest('published').published - ltz = tzinfo.LocalTimezone(d) - latest_published = rfc3339_date(d.replace(tzinfo=ltz)) + latest_published = rfc3339_date(timezone.make_aware(d, TZ)) self.assertEqual(updated, latest_published) @@ -253,8 +267,7 @@ class SyndicationFeedTest(FeedTestCase): updated = feed.getElementsByTagName('updated')[0].firstChild.wholeText d = Entry.objects.exclude(pk=5).latest('updated').updated - ltz = tzinfo.LocalTimezone(d) - latest_updated = rfc3339_date(d.replace(tzinfo=ltz)) + latest_updated = rfc3339_date(timezone.make_aware(d, TZ)) self.assertEqual(updated, latest_updated) @@ -308,8 +321,7 @@ class SyndicationFeedTest(FeedTestCase): updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText d = Entry.objects.latest('published').published - ltz = tzinfo.LocalTimezone(d) - latest = rfc3339_date(d.replace(tzinfo=ltz)) + latest = rfc3339_date(timezone.make_aware(d, TZ)) self.assertEqual(updated, latest) diff --git a/tests/template_tests/filters.py b/tests/template_tests/filters.py index 142f56f073..317b8bcd23 100644 --- a/tests/template_tests/filters.py +++ b/tests/template_tests/filters.py @@ -11,9 +11,9 @@ from __future__ import unicode_literals from datetime import date, datetime, time, timedelta from django.test.utils import str_prefix -from django.utils.tzinfo import LocalTimezone, FixedOffset -from django.utils.safestring import mark_safe from django.utils.encoding import python_2_unicode_compatible +from django.utils.safestring import mark_safe +from django.utils import timezone # These two classes are used to test auto-escaping of __unicode__ output. @python_2_unicode_compatible @@ -31,8 +31,8 @@ class SafeClass: # 'expected string output' or Exception class) def get_filter_tests(): now = datetime.now() - now_tz = datetime.now(LocalTimezone(now)) - now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) # imaginary time zone + now_tz = timezone.make_aware(now, timezone.get_default_timezone()) + now_tz_i = timezone.localtime(now_tz, timezone.get_fixed_timezone(195)) today = date.today() # NOTE: \xa0 avoids wrapping between value and unit @@ -355,7 +355,7 @@ def get_filter_tests(): 'date04': (r'{{ d|date:"o" }}', {'d': datetime(2008, 12, 29)}, '2009'), 'date05': (r'{{ d|date:"o" }}', {'d': datetime(2010, 1, 3)}, '2009'), # Timezone name - 'date06': (r'{{ d|date:"e" }}', {'d': datetime(2009, 3, 12, tzinfo=FixedOffset(30))}, '+0030'), + 'date06': (r'{{ d|date:"e" }}', {'d': datetime(2009, 3, 12, tzinfo=timezone.get_fixed_timezone(30))}, '+0030'), 'date07': (r'{{ d|date:"e" }}', {'d': datetime(2009, 3, 12)}, ''), # Ticket 19370: Make sure |date doesn't blow up on a midnight time object 'date08': (r'{{ t|date:"H:i" }}', {'t': time(0, 1)}, '00:01'), @@ -363,7 +363,7 @@ def get_filter_tests(): # Ticket 20693: Add timezone support to built-in time template filter 'time01': (r'{{ dt|time:"e:O:T:Z" }}', {'dt': now_tz_i}, '+0315:+0315:+0315:11700'), 'time02': (r'{{ dt|time:"e:T" }}', {'dt': now}, ':' + now_tz.tzinfo.tzname(now_tz)), - 'time03': (r'{{ t|time:"P:e:O:T:Z" }}', {'t': time(4, 0, tzinfo=FixedOffset(30))}, '4 a.m.::::'), + 'time03': (r'{{ t|time:"P:e:O:T:Z" }}', {'t': time(4, 0, tzinfo=timezone.get_fixed_timezone(30))}, '4 a.m.::::'), 'time04': (r'{{ t|time:"P:e:O:T:Z" }}', {'t': time(4, 0)}, '4 a.m.::::'), 'time05': (r'{{ d|time:"P:e:O:T:Z" }}', {'d': today}, ''), 'time06': (r'{{ obj|time:"P:e:O:T:Z" }}', {'obj': 'non-datetime-value'}, ''), diff --git a/tests/utils_tests/test_dateformat.py b/tests/utils_tests/test_dateformat.py index 2f682b6ce0..a1980b7930 100644 --- a/tests/utils_tests/test_dateformat.py +++ b/tests/utils_tests/test_dateformat.py @@ -1,42 +1,28 @@ from __future__ import unicode_literals from datetime import datetime, date -import os import time -import unittest +from django.test import TestCase +from django.test.utils import override_settings from django.utils.dateformat import format from django.utils import dateformat +from django.utils.timezone import utc, get_fixed_timezone, get_default_timezone from django.utils import translation -from django.utils.timezone import utc -from django.utils.tzinfo import FixedOffset, LocalTimezone -class DateFormatTests(unittest.TestCase): +@override_settings(TIME_ZONE='Europe/Copenhagen') +class DateFormatTests(TestCase): + + # Run tests that require a time zone only when the OS supports it. + tz_tests = hasattr(time, 'tzset') + def setUp(self): - self.old_TZ = os.environ.get('TZ') - os.environ['TZ'] = 'Europe/Copenhagen' self._orig_lang = translation.get_language() translation.activate('en-us') - try: - # Check if a timezone has been set - time.tzset() - self.tz_tests = True - except AttributeError: - # No timezone available. Don't run the tests that require a TZ - self.tz_tests = False - def tearDown(self): translation.activate(self._orig_lang) - if self.old_TZ is None: - del os.environ['TZ'] - else: - os.environ['TZ'] = self.old_TZ - - # Cleanup - force re-evaluation of TZ environment variable. - if self.tz_tests: - time.tzset() def test_date(self): d = date(2009, 5, 16) @@ -47,14 +33,14 @@ class DateFormatTests(unittest.TestCase): self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt) def test_datetime_with_local_tzinfo(self): - ltz = LocalTimezone(datetime.now()) + ltz = get_default_timezone() dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=ltz) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt.replace(tzinfo=None)) def test_datetime_with_tzinfo(self): - tz = FixedOffset(-510) - ltz = LocalTimezone(datetime.now()) + tz = get_fixed_timezone(-510) + ltz = get_default_timezone() dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz), dt) self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt) @@ -128,7 +114,7 @@ class DateFormatTests(unittest.TestCase): timestamp = datetime(2008, 5, 19, 11, 45, 23, 123456) # 3h30m to the west of UTC - tz = FixedOffset(-3*60 - 30) + tz = get_fixed_timezone(-210) aware_dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz) if self.tz_tests: diff --git a/tests/utils_tests/test_dateparse.py b/tests/utils_tests/test_dateparse.py index 836c26c573..61afff9a9c 100644 --- a/tests/utils_tests/test_dateparse.py +++ b/tests/utils_tests/test_dateparse.py @@ -4,7 +4,7 @@ from datetime import date, time, datetime import unittest from django.utils.dateparse import parse_date, parse_time, parse_datetime -from django.utils.tzinfo import FixedOffset +from django.utils.timezone import get_fixed_timezone class DateParseTests(unittest.TestCase): @@ -34,11 +34,11 @@ class DateParseTests(unittest.TestCase): self.assertEqual(parse_datetime('2012-4-9 4:8:16'), datetime(2012, 4, 9, 4, 8, 16)) self.assertEqual(parse_datetime('2012-04-23T09:15:00Z'), - datetime(2012, 4, 23, 9, 15, 0, 0, FixedOffset(0))) + datetime(2012, 4, 23, 9, 15, 0, 0, get_fixed_timezone(0))) self.assertEqual(parse_datetime('2012-4-9 4:8:16-0320'), - datetime(2012, 4, 9, 4, 8, 16, 0, FixedOffset(-200))) + datetime(2012, 4, 9, 4, 8, 16, 0, get_fixed_timezone(-200))) self.assertEqual(parse_datetime('2012-04-23T10:20:30.400+02:30'), - datetime(2012, 4, 23, 10, 20, 30, 400000, FixedOffset(150))) + datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(150))) # Invalid inputs self.assertEqual(parse_datetime('20120423091500'), None) self.assertRaises(ValueError, parse_datetime, '2012-04-56T09:15:90') diff --git a/tests/utils_tests/test_feedgenerator.py b/tests/utils_tests/test_feedgenerator.py index a801305f17..99d9f5ff7d 100644 --- a/tests/utils_tests/test_feedgenerator.py +++ b/tests/utils_tests/test_feedgenerator.py @@ -4,7 +4,7 @@ import datetime import unittest from django.utils import feedgenerator -from django.utils import tzinfo +from django.utils.timezone import get_fixed_timezone class FeedgeneratorTest(unittest.TestCase): @@ -43,7 +43,7 @@ class FeedgeneratorTest(unittest.TestCase): Test rfc2822_date() correctly formats datetime objects with tzinfo. """ self.assertEqual( - feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=tzinfo.FixedOffset(datetime.timedelta(minutes=60)))), + feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=get_fixed_timezone(60))), "Fri, 14 Nov 2008 13:37:00 +0100" ) @@ -70,7 +70,7 @@ class FeedgeneratorTest(unittest.TestCase): Test rfc3339_date() correctly formats datetime objects with tzinfo. """ self.assertEqual( - feedgenerator.rfc3339_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=tzinfo.FixedOffset(datetime.timedelta(minutes=120)))), + feedgenerator.rfc3339_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=get_fixed_timezone(120))), "2008-11-14T13:37:00+02:00" ) diff --git a/tests/utils_tests/test_timesince.py b/tests/utils_tests/test_timesince.py index cdb95e6877..b454131b2d 100644 --- a/tests/utils_tests/test_timesince.py +++ b/tests/utils_tests/test_timesince.py @@ -4,7 +4,8 @@ import datetime import unittest from django.utils.timesince import timesince, timeuntil -from django.utils.tzinfo import LocalTimezone, FixedOffset +from django.utils import timezone + class TimesinceTests(unittest.TestCase): @@ -95,8 +96,8 @@ class TimesinceTests(unittest.TestCase): def test_different_timezones(self): """ When using two different timezones. """ now = datetime.datetime.now() - now_tz = datetime.datetime.now(LocalTimezone(now)) - now_tz_i = datetime.datetime.now(FixedOffset((3 * 60) + 15)) + now_tz = timezone.make_aware(now, timezone.get_default_timezone()) + now_tz_i = timezone.localtime(now_tz, timezone.get_fixed_timezone(195)) self.assertEqual(timesince(now), '0\xa0minutes') self.assertEqual(timesince(now_tz), '0\xa0minutes')