Commit 1109ebd7 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Optimized make_aware/naive by removing redundant checks. Refs #22625.

Also added tests with pytz and removed misplaced tests.
parent fa89acf1
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -306,9 +306,11 @@ def localtime(value, timezone=None):
    """
    if timezone is None:
        timezone = get_current_timezone()
    # If `value` is naive, astimezone() will raise a ValueError,
    # so we don't need to perform a redundant check.
    value = value.astimezone(timezone)
    if hasattr(timezone, 'normalize'):
        # available for pytz time zones
        # This method is available for pytz time zones.
        value = timezone.normalize(value)
    return value

@@ -351,13 +353,15 @@ def make_aware(value, timezone):
    """
    Makes a naive datetime.datetime in a given time zone aware.
    """
    if is_aware(value):
        raise ValueError("make_aware expects a naive value, got %s" % value)
    if hasattr(timezone, 'localize'):
        # available for pytz time zones
        # This method is available for pytz time zones.
        return timezone.localize(value, is_dst=None)
    else:
        # may be wrong around DST changes
        # Check that we won't overwrite the timezone of an aware datetime.
        if is_aware(value):
            raise ValueError(
                    "make_aware expects a naive datetime, got %s" % value)
        # This may be wrong around DST changes!
        return value.replace(tzinfo=timezone)


@@ -365,10 +369,10 @@ def make_naive(value, timezone):
    """
    Makes an aware datetime.datetime naive in a given time zone.
    """
    if is_naive(value):
        raise ValueError("make_naive expects an aware value, got %s" % value)
    # If `value` is naive, astimezone() will raise a ValueError,
    # so we don't need to perform a redundant check.
    value = value.astimezone(timezone)
    if hasattr(timezone, 'normalize'):
        # available for pytz time zones
        # This method is available for pytz time zones.
        value = timezone.normalize(value)
    return value.replace(tzinfo=None)
+0 −28
Original line number Diff line number Diff line
@@ -1120,31 +1120,3 @@ class AdminTests(TestCase):
        with timezone.override(ICT):
            response = self.client.get(reverse('admin:timezones_timestamp_change', args=(t.pk,)))
        self.assertContains(response, t.created.astimezone(ICT).isoformat())


@override_settings(TIME_ZONE='Africa/Nairobi')
class UtilitiesTests(TestCase):

    def test_make_aware(self):
        self.assertEqual(
            timezone.make_aware(datetime.datetime(2011, 9, 1, 13, 20, 30), EAT),
            datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)
        )
        self.assertEqual(
            timezone.make_aware(datetime.datetime(2011, 9, 1, 10, 20, 30), UTC),
            datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC)
        )

    def test_make_naive(self):
        self.assertEqual(
            timezone.make_naive(datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT), EAT),
            datetime.datetime(2011, 9, 1, 13, 20, 30)
        )
        self.assertEqual(
            timezone.make_naive(datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT), UTC),
            datetime.datetime(2011, 9, 1, 10, 20, 30)
        )
        self.assertEqual(
            timezone.make_naive(datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC), UTC),
            datetime.datetime(2011, 9, 1, 10, 20, 30)
        )
+30 −0
Original line number Diff line number Diff line
@@ -3,10 +3,17 @@ import datetime
import pickle
import unittest

try:
    import pytz
except ImportError:
    pytz = None

from django.test import override_settings
from django.utils import timezone


if pytz is not None:
    CET = pytz.timezone("Europe/Paris")
EAT = timezone.get_fixed_timezone(180)      # Africa/Nairobi
ICT = timezone.get_fixed_timezone(420)      # Asia/Bangkok

@@ -19,6 +26,10 @@ class TimezoneTests(unittest.TestCase):
        local_now = timezone.localtime(now, local_tz)
        self.assertEqual(local_now.tzinfo, local_tz)

    def test_localtime_naive(self):
        with self.assertRaises(ValueError):
            timezone.localtime(datetime.datetime.now())

    def test_localtime_out_of_range(self):
        local_tz = timezone.LocalTimezone()
        long_ago = datetime.datetime(1900, 1, 1, tzinfo=timezone.utc)
@@ -96,3 +107,22 @@ class TimezoneTests(unittest.TestCase):
            datetime.datetime(2011, 9, 1, 13, 20, 30))
        with self.assertRaises(ValueError):
            timezone.make_naive(datetime.datetime(2011, 9, 1, 13, 20, 30), EAT)

    @unittest.skipIf(pytz is None, "this test requires pytz")
    def test_make_aware(self):
        self.assertEqual(
            timezone.make_aware(datetime.datetime(2011, 9, 1, 12, 20, 30), CET),
            CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)))
        with self.assertRaises(ValueError):
            timezone.make_aware(CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)), CET)

    @unittest.skipIf(pytz is None, "this test requires pytz")
    def test_make_aware_pytz(self):
        self.assertEqual(
            timezone.make_naive(CET.localize(datetime.datetime(2011, 9, 1, 12, 20, 30)), CET),
            datetime.datetime(2011, 9, 1, 12, 20, 30))
        self.assertEqual(
            timezone.make_naive(pytz.timezone("Asia/Bangkok").localize(datetime.datetime(2011, 9, 1, 17, 20, 30)), CET),
            datetime.datetime(2011, 9, 1, 12, 20, 30))
        with self.assertRaises(ValueError):
            timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30), CET)