util: fix time_format.iso_utc_time_to_seconds() so that it works even in London
authorZooko O'Whielacronx <zooko@zooko.com>
Thu, 11 Jun 2009 22:11:29 +0000 (15:11 -0700)
committerZooko O'Whielacronx <zooko@zooko.com>
Thu, 11 Jun 2009 22:11:29 +0000 (15:11 -0700)
src/allmydata/test/test_util.py
src/allmydata/util/time_format.py

index ca64b1f4c5ed322749c1e216b18fc6f659fdecdf..0f0fbba9a6b1abd76ff0ac6a718807b194b954bb 100644 (file)
@@ -765,6 +765,31 @@ class Limiter(unittest.TestCase):
 
 class TimeFormat(unittest.TestCase):
     def test_epoch(self):
+        return self._help_test_epoch()
+
+    def test_epoch_in_London(self):
+        # Europe/London is a particularly troublesome timezone.  Nowadays, its
+        # offset from GMT is 0.  But in 1970, its offset from GMT was 1.
+        # (Apparently in 1970 Britain had redefined standard time to be GMT+1
+        # and stayed in standard time all year round, whereas today
+        # Europe/London standard time is GMT and Europe/London Daylight
+        # Savings Time is GMT+1.)  The current implementation of
+        # time_format.iso_utc_time_to_localseconds() breaks if the timezone is
+        # Europe/London.  (As soon as this unit test is done then I'll change
+        # that implementation to something that works even in this case...)
+        origtz = os.environ.get('TZ')
+        os.environ['TZ'] = "Europe/London"
+        time.tzset()
+        try:
+            return self._help_test_epoch()
+        finally:
+            if origtz is None:
+                del os.environ['TZ']
+            else:
+                os.environ['TZ'] = origtz
+            time.tzset()
+
+    def _help_test_epoch(self):
         s = time_format.iso_utc_time_to_seconds("1970-01-01T00:00:01")
         self.failUnlessEqual(s, 1.0)
         s = time_format.iso_utc_time_to_seconds("1970-01-01_00:00:01")
index adaa5c1b79f60b8343d86e4390d5c4517787b5ac..aa0b64d8b269974f27d33c135e6b66b1f9f28703 100644 (file)
@@ -7,7 +7,7 @@
 # ISO-8601:
 # http://www.cl.cam.ac.uk/~mgk25/iso-time.html
 
-import datetime, re, time
+import datetime, os, re, time
 
 def iso_utc_date(now=None, t=time.time):
     if now is None:
@@ -42,10 +42,17 @@ def iso_utc_time_to_seconds(isotime, _conversion_re=re.compile(r"(?P<year>\d{4})
     else:
         subsecfloat = 0
 
-    localsecondsnodst = time.mktime( (year, month, day, hour, minute, second, 0, 1, 0) )
-    localsecondsnodst += subsecfloat
-    utcseconds = localsecondsnodst - time.timezone
-    return utcseconds
+    origtz = os.environ.get('TZ')
+    os.environ['TZ'] = "UTC"
+    time.tzset()
+    try:
+        return time.mktime( (year, month, day, hour, minute, second, 0, 1, 0) ) + subsecfloat
+    finally:
+        if origtz is None:
+            del os.environ['TZ']
+        else:
+            os.environ['TZ'] = origtz
+        time.tzset()
 
 def parse_duration(s):
     orig = s