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

Tim Peters tim.one@comcast.net
Tue, 24 Dec 2002 00:53:46 -0500


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

Modified Files:
      Tag: NameGeddon-branch
	_datetime.py doc.txt 
Log Message:
Implemented .replace() methods for date, datetime, datetimetz, time and
timetz.


=== Zope3/src/datetime/_datetime.py 1.1.2.1 => 1.1.2.2 ===
--- Zope3/src/datetime/_datetime.py:1.1.2.1	Mon Dec 23 14:30:38 2002
+++ Zope3/src/datetime/_datetime.py	Tue Dec 24 00:53:15 2002
@@ -255,6 +255,28 @@
         return offset
     raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))
 
+def _check_date_fields(year, month, day):
+    if not MINYEAR <= year <= MAXYEAR:
+        raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
+    if not 1 <= month <= 12:
+        raise ValueError('month must be in 1..12', month)
+    dim = _days_in_month(year, month)
+    if not 1 <= day <= dim:
+        raise ValueError('day must be in 1..%d' % dim, day)
+
+def _check_time_fields(hour, minute, second, microsecond):
+    if not 0 <= hour <= 23:
+        raise ValueError('hour must be in 0..23', hour)
+    if not 0 <= minute <= 59:
+        raise ValueError('minute must be in 0..59', minute)
+    if not 0 <= second <= 59:
+        raise ValueError('second must be in 0..59', second)
+    if not 0 <= microsecond <= 999999:
+        raise ValueError('microsecond must be in 0..999999', microsecond)
+
+def _check_tzinfo_arg(tz):
+    if tz is not None and not isinstance(tz, tzinfo):
+        raise TypeError("tzinfo argument must be None or of a tzinfo subclass")
 
 # This is a start at a struct tm workalike.  Goals:
 #
@@ -630,14 +652,7 @@
 
         year, month, day (required, base 1)
         """
-        if not MINYEAR <= year <= MAXYEAR:
-            raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR),
-                             year)
-        if not 1 <= month <= 12:
-            raise ValueError('month must be in 1..12', month)
-        dim = _days_in_month(year, month)
-        if not 1 <= day <= dim:
-            raise ValueError('day must be in 1..%d' % dim, day)
+        _check_date_fields(year, month, day)
         self.__year = year
         self.__month = month
         self.__day = day
@@ -721,6 +736,17 @@
         """
         return _ymd2ord(self.__year, self.__month, self.__day)
 
+    def replace(self, year=None, month=None, day=None):
+        """Return a new date with new values for the specified fields."""
+        if year is None:
+            year = self.__year
+        if month is None:
+            month = self.__month
+        if day is None:
+            day = self.__day
+        _check_date_fields(year, month, day)
+        return date(year, month, day)
+
     def __cmp__(self, other):
         "Three-way comparison."
         if isinstance(other, date):
@@ -849,14 +875,7 @@
         hour, minute (required)
         second, microsecond (default to zero)
         """
-        if not 0 <= hour <= 23:
-            raise ValueError('hour must be in 0..23', hour)
-        if not 0 <= minute <= 59:
-            raise ValueError('minute must be in 0..59', minute)
-        if not 0 <= second <= 59:
-            raise ValueError('second must be in 0..59', second)
-        if not 0 <= microsecond <= 999999:
-            raise ValueError('microsecond must be in 0..999999', microsecond)
+        _check_time_fields(hour, minute, second, microsecond)
         self.__hour = hour
         self.__minute = minute
         self.__second = second
@@ -922,6 +941,19 @@
                      0, 0, -1)
         return _wrap_strftime(self, fmt, timetuple)
 
+    def replace(self, hour=None, minute=None, second=None, microsecond=None):
+        """Return a new time with new values for the specified fields."""
+        if hour is None:
+            hour = self.hour
+        if minute is None:
+            minute = self.minute
+        if second is None:
+            second = self.second
+        if microsecond is None:
+            microsecond = self.microsecond
+        _check_time_fields(hour, minute, second, microsecond)
+        return time(hour, minute, second, microsecond)
+
     def __nonzero__(self):
         return (self.__hour != 0 or
                 self.__minute != 0 or
@@ -1008,10 +1040,7 @@
         second, microsecond (default to zero)
         tzinfo (default to None)
         """
-        import datetime
-        if tzinfo is not None and not isinstance(tzinfo, datetime.tzinfo):
-            raise TypeError("tzinfo argument must be None or of a tzinfo "
-                            "subclass")
+        _check_tzinfo_arg(tzinfo)
         super(timetz, self).__init__(hour, minute, second, microsecond)
         self.__tzinfo = tzinfo
 
@@ -1136,6 +1165,23 @@
             offset = timedelta(minutes=offset)
         return offset
 
+    def replace(self, hour=None, minute=None, second=None, microsecond=None,
+                tzinfo=True):
+        """Return a new timetz with new values for the specified fields."""
+        if hour is None:
+            hour = self.hour
+        if minute is None:
+            minute = self.minute
+        if second is None:
+            second = self.second
+        if microsecond is None:
+            microsecond = self.microsecond
+        if tzinfo is True:
+            tzinfo = self.tzinfo
+        _check_time_fields(hour, minute, second, microsecond)
+        _check_tzinfo_arg(tzinfo)
+        return timetz(hour, minute, second, microsecond, tzinfo)
+
     # Return an integer (or None) instead of a timedelta (or None).
     def _dst(self):
         offset = _call_tzinfo_method(self, self.__tzinfo, "dst")
@@ -1213,14 +1259,7 @@
         hour, minute, second, microsecond (default to zero)
         """
         super(datetime, self).__init__(year, month, day)
-        if not 0 <= hour <= 23:
-            raise ValueError('hour must be in 0..23', hour)
-        if not 0 <= minute <= 59:
-            raise ValueError('minute must be in 0..59', minute)
-        if not 0 <= second <= 59:
-            raise ValueError('second must be in 0..59', second)
-        if not 0 <= microsecond <= 999999:
-            raise ValueError('microsecond must be in 0..999999', microsecond)
+        _check_time_fields(hour, minute, second, microsecond)
         # XXX This duplicates __year, __month, __day for convenience :-(
         self.__year = year
         self.__month = month
@@ -1274,6 +1313,27 @@
                    time.hour, time.minute, time.second, time.microsecond)
     combine = classmethod(combine)
 
+    def replace(self, year=None, month=None, day=None, hour=None,
+                minute=None, second=None, microsecond=None):
+        """Return a new datetime with new values for the specified fields."""
+        if year is None:
+            year = self.year
+        if month is None:
+            month = self.month
+        if day is None:
+            day = self.day
+        if hour is None:
+            hour = self.hour
+        if minute is None:
+            minute = self.minute
+        if second is None:
+            second = self.second
+        if microsecond is None:
+            microsecond = self.microsecond
+        _check_date_fields(year, month, day)
+        _check_time_fields(hour, minute, second, microsecond)
+        return datetime(year, month, day, hour, minute, second, microsecond)
+
     # Conversions to string.
 
     def __repr__(self):
@@ -1435,10 +1495,7 @@
 
     def __init__(self, year, month, day, hour=0, minute=0, second=0,
                  microsecond=0, tzinfo=None):
-        import datetime
-        if tzinfo is not None and not isinstance(tzinfo, datetime.tzinfo):
-            raise TypeError("tzinfo argument must be None or of a tzinfo "
-                            "subclass")
+        _check_tzinfo_arg(tzinfo)
         super(datetimetz, self).__init__(year, month, day,
                                          hour, minute, second, microsecond)
         self.__tzinfo = tzinfo
@@ -1494,6 +1551,31 @@
         "Return the time part."
         return timetz(self.hour, self.minute, self.second, self.microsecond,
                       self.__tzinfo)
+
+    def replace(self, year=None, month=None, day=None, hour=None,
+                minute=None, second=None, microsecond=None, tzinfo=True):
+        """Return a new datetimetz with new values for the specified fields."""
+        if year is None:
+            year = self.year
+        if month is None:
+            month = self.month
+        if day is None:
+            day = self.day
+        if hour is None:
+            hour = self.hour
+        if minute is None:
+            minute = self.minute
+        if second is None:
+            second = self.second
+        if microsecond is None:
+            microsecond = self.microsecond
+        if tzinfo is True:
+            tzinfo = self.tzinfo
+        _check_date_fields(year, month, day)
+        _check_time_fields(hour, minute, second, microsecond)
+        _check_tzinfo_arg(tzinfo)
+        return datetimetz(year, month, day, hour, minute, second,
+                          microsecond, tzinfo)
 
     def isoformat(self, sep='T'):
         s = super(datetimetz, self).isoformat(sep)


=== Zope3/src/datetime/doc.txt 1.1.2.1 => 1.1.2.2 ===
--- Zope3/src/datetime/doc.txt:1.1.2.1	Mon Dec 23 14:30:38 2002
+++ Zope3/src/datetime/doc.txt	Tue Dec 24 00:53:15 2002
@@ -407,6 +407,11 @@
 
 Instance methods:
 
+  - replace(year=None, month=None, day=None)
+    Return a date with the same fields as self, except for those members
+    given in the argument list.  For example,
+    date(1, 1, 1).replace(year=2000) == date(2000, 1, 1).
+
   - timetuple()
     Return a 9-element tuple of the form returned by time.localtime().
     The hours, minutes and seconds are 0, and the DST flag is -1.
@@ -612,6 +617,11 @@
   - time()
     Return time object with same hour, minute, second and microsecond.
 
+  - replace(year=None, month=None, day=None, hour=None, minute=None,
+            second=None, microsecond=None)
+    Return a datetime with the same fields as self, except for those
+    members given in the argument list.
+
   - timetuple()
     Return a 9-element tuple of the form returned by time.localtime().
     The DST flag is -1.   d.timetuple() is equivalent to
@@ -722,6 +732,10 @@
 
 Instance methods:
 
+  - replace(hour=None, minute=None, second=None, microsecond=None)
+    Return a time with the same fields as self, except for those
+    members given in the argument list.
+
   - isoformat()
     Return a string representing the time in ISO 8601 format,
         HH:MM:SS.mmmmmm
@@ -947,6 +961,13 @@
     If self.tzinfo is None, returns None, else self.tzinfo.dst(self),
     converted to a timedelta object.
 
+  - replace(hour=None, minute=None, second=None, microsecond=None,
+            tzinfo=True)
+    Return a timetz with the same fields as self, except for those
+    members given in the argument list.  Note that the tzinfo argument
+    defaults to True instead of to None.  This is so you can specify
+    tzinfo=None to remove a timetz's tzinfo member.
+
 
 class datetimetz
 ================
@@ -1094,6 +1115,13 @@
   - dst()
     If self.tzinfo is None, returns None, else self.tzinfo.dst(self),
     converted to a timedelta object.
+
+  - replace(year=None, month=None, day=None, hour=None, minute=None,
+            second=None, microsecond=None, tzinfo=True)
+    Return a datet with the same fields as self, except for those
+    members given in the argument list.  Note that the tzinfo argument
+    defaults to True instead of to None.  This is so you can specify
+    tzinfo=None to remove a datetimetz's tzinfo member.
 
   - timetuple()
     Like datetime.timetuple(), but sets the tm_isdst flag according to