[Zope3-checkins] CVS: Zope3/src/datetime/tests - test_datetime.py:1.15

Tim Peters tim.one@comcast.net
Fri, 3 Jan 2003 23:52:51 -0500


Update of /cvs-repository/Zope3/src/datetime/tests
In directory cvs.zope.org:/tmp/cvs-serv6639/src/datetime/tests

Modified Files:
	test_datetime.py 
Log Message:
A new implementation of astimezone() that does what we agreed on in all
cases, plus even tougher tests of that.  This implementation follows
the correctness proof very closely, and should also be quicker (yes,
I wrote the proof before the code, and the code proves the proof <wink>).


=== Zope3/src/datetime/tests/test_datetime.py 1.14 => 1.15 ===
--- Zope3/src/datetime/tests/test_datetime.py:1.14	Thu Jan  2 16:12:30 2003
+++ Zope3/src/datetime/tests/test_datetime.py	Fri Jan  3 23:52:49 2003
@@ -2602,7 +2602,7 @@
 utc_real = FixedOffset(0, "UTC", 0)
 # For better test coverage, we want another flavor of UTC that's west of
 # the Eastern and Pacific timezones.
-utc_fake = FixedOffset(-12, "UTCfake", 0)
+utc_fake = FixedOffset(-12*60, "UTCfake", 0)
 
 class TestTimezoneConversions(unittest.TestCase):
     # The DST switch times for 2002, in local time.
@@ -2653,25 +2653,17 @@
         # 1:MM:SS is taken to be daylight time, and 2:MM:SS as
         # standard time.  The hour 1:MM:SS standard time ==
         # 2:MM:SS daylight time can't be expressed in local time.
+        # Nevertheless, we want conversion back from UTC to mimic
+        # the local clock's "repeat an hour" behavior.
         nexthour_utc = asutc + HOUR
+        nexthour_tz = nexthour_utc.astimezone(tz)
         if dt.date() == dstoff.date() and dt.hour == 1:
             # We're in the hour before DST ends.  The hour after
-            # is ineffable.
-            # For concreteness, picture Eastern.  during is of
-            # the form 1:MM:SS, it's daylight time, so that's
-            # 5:MM:SS UTC.  Adding an hour gives 6:MM:SS UTC.
-            # Daylight time ended at 2+4 == 6:00:00 UTC, so
-            # 6:MM:SS is (correctly) taken to be standard time.
-            # But standard time is at offset -5, and that maps
-            # right back to the 1:MM:SS Eastern we started with.
-            # That's correct, too, *if* 1:MM:SS were taken as
-            # being standard time.  But it's not -- on this day
-            # it's taken as daylight time.
-            self.assertRaises(ValueError,
-                              nexthour_utc.astimezone, tz)
+            # is ineffable.  We want the conversion back to repeat 1:MM.
+            expected_diff = ZERO
         else:
-            nexthour_tz = nexthour_utc.astimezone(utc)
-            self.assertEqual(nexthour_tz - dt, HOUR)
+            expected_diff = HOUR
+        self.assertEqual(nexthour_tz - dt, expected_diff)
 
     # Check a time that's outside DST.
     def checkoutside(self, dt, tz, utc):
@@ -2748,6 +2740,31 @@
         expected = self.dston.replace(hour=1)
         got = sixutc.astimezone(Eastern).astimezone(None)
         self.assertEqual(expected, got)
+
+        # Now on the day DST ends, we want "repeat an hour" behavior.
+        #  UTC  4:MM  5:MM  6:MM  7:MM  checking these
+        #  EST 23:MM  0:MM  1:MM  2:MM
+        #  EDT  0:MM  1:MM  2:MM  3:MM
+        # wall  0:MM  1:MM  1:MM  2:MM  against these
+        for utc in utc_real, utc_fake:
+            for tz in Eastern, Pacific:
+                first_std_hour = self.dstoff - timedelta(hours=3) # 23:MM
+                # Convert that to UTC.
+                first_std_hour -= tz.utcoffset(None)
+                # Adjust for possibly fake UTC.
+                asutc = first_std_hour + utc.utcoffset(None)
+                # First UTC hour to convert; this is 4:00 when utc=utc_real &
+                # tz=Eastern.
+                asutcbase = asutc.replace(tzinfo=utc)
+                for tzhour in (0, 1, 1, 2):
+                    expectedbase = self.dstoff.replace(hour=tzhour)
+                    for minute in 0, 30, 59:
+                        expected = expectedbase.replace(minute=minute)
+                        asutc = asutcbase.replace(minute=minute)
+                        astz = asutc.astimezone(tz)
+                        self.assertEqual(astz.replace(tzinfo=None), expected)
+                    asutcbase += HOUR
+
 
     def test_bogus_dst(self):
         class ok(tzinfo):