[Zope3-checkins] CVS: Zope3/src/datetime - _datetime.py:1.17 doc.txt:1.9

Tim Peters tim.one@comcast.net
Thu, 2 Jan 2003 16:13:01 -0500


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

Modified Files:
	_datetime.py doc.txt 
Log Message:
The tzinfo methods utcoffset() and dst() must return a timedelta object 
(or None) now.  In 2.3a1 they could also return an int or long, but that 
was an unhelpfully redundant leftover from an earlier version wherein 
they couldn't return a timedelta.  TOOWTDI.


=== Zope3/src/datetime/_datetime.py 1.16 => 1.17 ===
--- Zope3/src/datetime/_datetime.py:1.16	Thu Jan  2 14:27:12 2003
+++ Zope3/src/datetime/_datetime.py	Thu Jan  2 16:12:29 2003
@@ -229,7 +229,7 @@
 
 # name is the offset-producing method, "utcoffset" or "dst".
 # offset is what it returned.
-# If offset isn't None, int, long, or timedelta, raises TypeError.
+# If offset isn't None or timedelta, raises TypeError.
 # If offset is None, returns None.
 # Else offset is checked for being in range, and a whole # of minutes.
 # If it is, its integer value is returned.  Else ValueError is raised.
@@ -237,20 +237,19 @@
     assert name in ("utcoffset", "dst")
     if offset is None:
         return None
-    if not isinstance(offset, (int, long, timedelta)):
-        raise TypeError("tzinfo.%s() must return None, integer "
+    if not isinstance(offset, timedelta):
+        raise TypeError("tzinfo.%s() must return None "
                         "or timedelta, not '%s'" % (name, type(offset)))
-    if isinstance(offset, timedelta):
-        days = offset.days
-        if days < -1 or days > 0:
-            offset = 1440  # trigger out-of-range
-        else:
-            seconds = days * 86400 + offset.seconds
-            minutes, seconds = divmod(seconds, 60)
-            if seconds or offset.microseconds:
-                raise ValueError("tzinfo.%s() must return a whole number "
-                                 "of minutes" % name)
-            offset = minutes
+    days = offset.days
+    if days < -1 or days > 0:
+        offset = 1440  # trigger out-of-range
+    else:
+        seconds = days * 86400 + offset.seconds
+        minutes, seconds = divmod(seconds, 60)
+        if seconds or offset.microseconds:
+            raise ValueError("tzinfo.%s() must return a whole number "
+                             "of minutes" % name)
+        offset = minutes
     if -1440 < offset < 1440:
         return offset
     raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))


=== Zope3/src/datetime/doc.txt 1.8 => 1.9 ===
--- Zope3/src/datetime/doc.txt:1.8	Thu Jan  2 14:27:12 2003
+++ Zope3/src/datetime/doc.txt	Thu Jan  2 16:12:29 2003
@@ -782,10 +782,10 @@
     is intended to be the total offset from UTC; for example, if a
     tzinfo object represents both time zone and DST adjustments,
     utcoffset() should return their sum.  If the UTC offset isn't known,
-    return None.  Else the value returned must be an int, long, or
-    timedelta object, in the range -1439 to 1439 inclusive (1440 = 24*60;
-    the magnitude of the offset must be less than one day, and must be
-    a whole number of minutes).  Most implementations of utcoffset()
+    return None.  Else the value returned must be a timedelta object
+    specifying a whole number of minutes in the range -1439 to 1439
+    inclusive (1440 = 24*60; the magnitude of the offset must be less
+    than one day).  Most implementations of utcoffset()
     will probably look like:
 
         return CONSTANT  # fixed-offset class
@@ -797,14 +797,14 @@
   - dst(self, dt)
     Return the DST offset, in minutes east of UTC, or None if DST
     information isn't known.  Return 0 if DST is not in effect.
-    If DST is in effect, return an int, long, or timedelta object, in
-    the range -1439 to 1439 inclusive.  This must be a whole number of
-    minutes.  Note that DST offset, if applicable, has already been added
-    to the UTC offset returned by utcoffset(), so there's no need to
-    consult dst() unless you're interested in displaying DST info
-    separately.  For example, datetimetz.timetuple() calls its
-    tzinfo object's dst() method to determine how the tm_isdst flag
-    should be set.
+    If DST is in effect, return the offset as a timedelta object (see
+    utcoffset() for details). Note that DST offset, if applicable, has
+    already been added to the UTC offset returned by utcoffset(), so
+    there's no need to consult dst() unless you're interested in
+    displaying DST info separately.  For example, datetimetz.timetuple()
+    calls its tzinfo object's dst() method to determine how the tm_isdst
+    flag should be set, and datetimetz.astimezone() calls dst() to
+    account for DST changes when crossing time zones.
 
     An instance tz of a tzinfo subclass that models both standard and
     daylight times must be consistent in this sense:
@@ -849,42 +849,56 @@
 
 Example tzinfo classes:
 
-   class UTC(tzinfo):
-        "UTC"
+    from datetime import tzinfo, timedelta
+
+    ZERO = timedelta(0)
+
+    class UTC(tzinfo):
+        """UTC"""
+
         def utcoffset(self, dt):
-            return 0
+            return ZERO
+
         def tzname(self, dt):
             return "UTC"
+
         def dst(self, dt):
-            return 0
+            return ZERO
 
     class FixedOffset(tzinfo):
-        "Fixed offset in minutes east from UTC"
+        """Fixed offset in minutes east from UTC."""
+
         def __init__(self, offset, name):
             self.__offset = offset
             self.__name = name
+
         def utcoffset(self, dt):
             return self.__offset
+
         def tzname(self, dt):
             return self.__name
+
         def dst(self, dt):
-            # It depends on more than we know in an example.
-            return None # Indicate we don't know
+            return ZERO
 
     import time
+
     class LocalTime(tzinfo):
-        "Local time as defined by the operating system"
+        """Local time as defined by the operating system."""
+
         def _isdst(self, dt):
             t = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
                  -1, -1, -1)
             # XXX This may fail for years < 1970 or >= 2038
             t = time.localtime(time.mktime(t))
             return t.tm_isdst > 0
+
         def utcoffset(self, dt):
             if self._isdst(dt):
-                return -time.timezone/60
+                return timedelta(seconds=-time.timezone//60)
             else:
-                return -time.altzone/60
+                return timedelta(seconds=-time.altzone//60)
+
         def tzname(self, dt):
             return time.tzname[self._isdst(dt)]