diff --git a/django/test/signals.py b/django/test/signals.py index ed16831d42..81808dfa3c 100644 --- a/django/test/signals.py +++ b/django/test/signals.py @@ -1,27 +1,47 @@ +import os +import time + from django.conf import settings from django.db import connections from django.dispatch import receiver, Signal from django.template import context +from django.utils import timezone template_rendered = Signal(providing_args=["template", "context"]) setting_changed = Signal(providing_args=["setting", "value"]) + @receiver(setting_changed) def update_connections_time_zone(**kwargs): + if kwargs['setting'] == 'TIME_ZONE': + # Reset process time zone + if hasattr(time, 'tzset'): + if kwargs['value']: + os.environ['TZ'] = kwargs['value'] + else: + os.environ.pop('TZ', None) + time.tzset() + + # Reset local time zone cache + timezone._localtime = None + + # Reset the database connections' time zone if kwargs['setting'] == 'USE_TZ' and settings.TIME_ZONE != 'UTC': USE_TZ, TIME_ZONE = kwargs['value'], settings.TIME_ZONE elif kwargs['setting'] == 'TIME_ZONE' and not settings.USE_TZ: USE_TZ, TIME_ZONE = settings.USE_TZ, kwargs['value'] - else: # no need to change the database connnections' time zones + else: + # no need to change the database connnections' time zones return - tz = 'UTC' if USE_TZ else TIME_ZONE for conn in connections.all(): + conn.settings_dict['TIME_ZONE'] = tz tz_sql = conn.ops.set_time_zone_sql() if tz_sql: conn.cursor().execute(tz_sql, [tz]) + @receiver(setting_changed) def clear_context_processors_cache(**kwargs): if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS': diff --git a/django/utils/timezone.py b/django/utils/timezone.py index 0bba97e736..d9d9636023 100644 --- a/django/utils/timezone.py +++ b/django/utils/timezone.py @@ -95,7 +95,6 @@ utc = pytz.utc if pytz else UTC() # In order to avoid accessing the settings at compile time, # wrap the expression in a function and cache the result. -# If you change settings.TIME_ZONE in tests, reset _localtime to None. _localtime = None def get_default_timezone(): diff --git a/tests/modeltests/timezones/tests.py b/tests/modeltests/timezones/tests.py index 7505503d1f..90bc1f3a18 100644 --- a/tests/modeltests/timezones/tests.py +++ b/tests/modeltests/timezones/tests.py @@ -50,32 +50,8 @@ requires_tz_support = skipUnless(TZ_SUPPORT, "time zone, but your operating system isn't able to do that.") -class BaseDateTimeTests(TestCase): - - @classmethod - def setUpClass(self): - self._old_time_zone = settings.TIME_ZONE - settings.TIME_ZONE = connection.settings_dict['TIME_ZONE'] = 'Africa/Nairobi' - timezone._localtime = None - if TZ_SUPPORT: - self._old_tz = os.environ.get('TZ') - os.environ['TZ'] = 'Africa/Nairobi' - time.tzset() - - @classmethod - def tearDownClass(self): - settings.TIME_ZONE = connection.settings_dict['TIME_ZONE'] = self._old_time_zone - timezone._localtime = None - if TZ_SUPPORT: - if self._old_tz is None: - del os.environ['TZ'] - else: - os.environ['TZ'] = self._old_tz - time.tzset() - - -@override_settings(USE_TZ=False) -class LegacyDatabaseTests(BaseDateTimeTests): +@override_settings(TIME_ZONE='Africa/Nairobi', USE_TZ=False) +class LegacyDatabaseTests(TestCase): def test_naive_datetime(self): dt = datetime.datetime(2011, 9, 1, 13, 20, 30) @@ -269,8 +245,8 @@ class LegacyDatabaseTests(BaseDateTimeTests): transform=lambda d: d) -@override_settings(USE_TZ=True) -class NewDatabaseTests(BaseDateTimeTests): +@override_settings(TIME_ZONE='Africa/Nairobi', USE_TZ=True) +class NewDatabaseTests(TestCase): @requires_tz_support def test_naive_datetime(self): @@ -486,7 +462,8 @@ class NewDatabaseTests(BaseDateTimeTests): self.assertEqual(e.dt, None) -class SerializationTests(BaseDateTimeTests): +@override_settings(TIME_ZONE='Africa/Nairobi') +class SerializationTests(TestCase): # Backend-specific notes: # - JSON supports only milliseconds, microseconds will be truncated. @@ -639,8 +616,9 @@ class SerializationTests(BaseDateTimeTests): obj = serializers.deserialize('yaml', data).next().object self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) -@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True) -class TemplateTests(BaseDateTimeTests): + +@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True) +class TemplateTests(TestCase): @requires_tz_support def test_localtime_templatetag_and_filters(self): @@ -723,10 +701,8 @@ class TemplateTests(BaseDateTimeTests): tpl = Template("{% load tz %}{{ dt|localtime }}|{{ dt|utc }}") ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30)}) - timezone._localtime = None with self.settings(TIME_ZONE='Europe/Paris'): self.assertEqual(tpl.render(ctx), "2011-09-01T12:20:30+02:00|2011-09-01T10:20:30+00:00") - timezone._localtime = None # Use a pytz timezone as argument tpl = Template("{% load tz %}{{ dt|timezone:tz }}") @@ -864,11 +840,9 @@ class TemplateTests(BaseDateTimeTests): tpl = Template("{% load tz %}{{ dt }}") ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30, tzinfo=EAT)}) - timezone._localtime = None with self.settings(TIME_ZONE=None): # the actual value depends on the system time zone of the host self.assertTrue(tpl.render(ctx).startswith("2011")) - timezone._localtime = None @requires_tz_support def test_now_template_tag_uses_current_time_zone(self): @@ -879,8 +853,8 @@ class TemplateTests(BaseDateTimeTests): self.assertEqual(tpl.render(Context({})), "+0700") -@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=False) -class LegacyFormsTests(BaseDateTimeTests): +@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=False) +class LegacyFormsTests(TestCase): def test_form(self): form = EventForm({'dt': u'2011-09-01 13:20:30'}) @@ -914,8 +888,8 @@ class LegacyFormsTests(BaseDateTimeTests): self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 13, 20, 30)) -@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True) -class NewFormsTests(BaseDateTimeTests): +@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True) +class NewFormsTests(TestCase): @requires_tz_support def test_form(self): @@ -960,8 +934,8 @@ class NewFormsTests(BaseDateTimeTests): self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC)) -@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True) -class AdminTests(BaseDateTimeTests): +@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True) +class AdminTests(TestCase): urls = 'modeltests.timezones.urls' fixtures = ['tz_users.xml'] @@ -1012,7 +986,8 @@ class AdminTests(BaseDateTimeTests): self.assertContains(response, t.created.astimezone(ICT).isoformat()) -class UtilitiesTests(BaseDateTimeTests): +@override_settings(TIME_ZONE='Africa/Nairobi') +class UtilitiesTests(TestCase): def test_make_aware(self): self.assertEqual(