[Python-checkins] CVS: python/nondist/sandbox/datetime datetime.py,1.12,1.13 test_datetime.py,1.8,1.9

Guido van Rossum gvanrossum@users.sourceforge.net
Sat, 02 Mar 2002 14:33:49 -0800


Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory usw-pr-cvs1:/tmp/cvs-serv12052

Modified Files:
	datetime.py test_datetime.py 
Log Message:
- Add computations on datetime instances (__add__, __radd__ and __sub__)

- Fix docstring of _date2num()

- Add XXX comment about how we derive the default tzoffset

- Add __repr__ and __str__ to class datetime

- In _test(), run the tests from test_datetime



Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** datetime.py	2 Mar 2002 21:09:50 -0000	1.12
--- datetime.py	2 Mar 2002 22:33:46 -0000	1.13
***************
*** 48,52 ****
  
  def _date2num(date):
!     "datetime object -> day ordinal, considering 01-Jan-0000 as day 1."
      assert isinstance(date, datetime)
      return (_days_before_year(date.year) +
--- 48,52 ----
  
  def _date2num(date):
!     "datetime object -> day ordinal, considering 01-Jan-0001 as day 1."
      assert isinstance(date, datetime)
      return (_days_before_year(date.year) +
***************
*** 232,235 ****
--- 232,237 ----
              raise ValueError('microsecond must be in 0..999999', microsecond)
          if tzoffset is None:
+             # XXX This decides whether local time is DST or not once,
+             # and never changes its mind, regardless how long we run
              if datetime.__isdst is None:
                  datetime.__isdst = _time.localtime()[-1]
***************
*** 279,282 ****
--- 281,302 ----
      utcnow = classmethod(utcnow)
  
+     def __repr__(self):
+         L = [self.__year, self.__month, self.__day, # These are never zero
+              self.__hour, self.__minute, self.__second, self.__microsecond]
+         while L[-1] == 0:
+             del L[-1]
+         s = ", ".join(map(str, L))
+         return "datetime(%s, tzoffset=%d)" % (s, self.__tzoffset)
+ 
+     def __str__(self):
+         if self.__tzoffset == 0:
+             return self.ctime() + " UTC"
+         if self.__tzoffset > 0:
+             h, m = divmod(self.__tzoffset, 60)
+         else:
+             h, m = divmod(-self.__tzoffset, 60)
+             h = -h
+         return self.ctime() + " %+03d:%02d" % (h, m)
+ 
      # Read-only field accessors
      year = property(lambda self: self.__year,
***************
*** 385,398 ****
          return _time.strftime(fmt, _time.gmtime(self._mktime()))
  
!     # __add__, __sub__?
  
  def _test():
!     now = _time.time()
!     print _time.ctime(now)
!     t = datetime.fromtimestamp(now)
!     print t.ctime(), divmod(t.tzoffset, 60), t.hour
!     u = datetime.utcfromtimestamp(now)
!     print u.utcctime(), divmod(u.tzoffset, 60), u.hour
!     assert t == u
  
  if __name__ == "__main__":
--- 405,449 ----
          return _time.strftime(fmt, _time.gmtime(self._mktime()))
  
!     # Computations
! 
!     def __add__(self, other):
!         if isinstance(other, timedelta):
!             hh, mm, ss, us = (self.__hour,
!                               self.__minute,
!                               self.__second + other.seconds,
!                               self.__microsecond + other.microseconds)
!             carry_ss, us = divmod(us, 1000000)
!             carry_mm, ss = divmod(ss+carry_ss, 60)
!             carry_hh, mm = divmod(mm+carry_mm, 60)
!             days, hh = divmod(hh+carry_hh, 24)
!             result = _num2date(days + other.days + _date2num(self))
!             result.__hour = hh
!             result.__minute = mm
!             result.__second = ss
!             result.__microsecond = us
!             result.__tzoffset = self.__tzoffset
!             return result
!         return NotImplemented
! 
!     __radd__ = __add__
! 
!     def __sub__(self, other):
!        if isinstance(other, timedelta):
!            return self + -other
!        if isinstance(other, datetime):
!            days1 = _date2num(self)
!            days2 = _date2num(other)
!            secs1 = (self.__second + 60 * (self.__minute - self.__tzoffset) +
!                     self.__hour * 3600)
!            secs2 = (other.__second + 60 * (other.__minute - other.__tzoffset) +
!                     other.__hour * 3600)
!            return timedelta(days1 - days2, secs1 - secs2,
!                             self.__microsecond - other.__microsecond)
!        return NotImplemented
! 
  
  def _test():
!     import test_datetime
!     test_datetime.test_main()
  
  if __name__ == "__main__":

Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** test_datetime.py	2 Mar 2002 21:09:50 -0000	1.8
--- test_datetime.py	2 Mar 2002 22:33:46 -0000	1.9
***************
*** 40,43 ****
--- 40,44 ----
          self.assertEqual(_num2date(710347), d)
  
+         # XXX To speed up this loop, use range(MINYEAR, MAXYEAR + 1, 11)
          for year in range(MINYEAR, MAXYEAR + 1):
              base = datetime(year, 1, 1)
***************
*** 132,135 ****
--- 133,184 ----
          self.assertEqual(c*1000, timedelta(0, 1))
          self.assertEqual(1000*c, timedelta(0, 1))
+ 
+     def test_computations(self):
+         a = datetime(2002, 1, 31)
+         b = datetime(1956, 1, 31)
+         diff = a-b
+         self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4)))
+         self.assertEqual(diff.seconds, 0)
+         self.assertEqual(diff.microseconds, 0)
+         a = datetime(2002, 3, 2, 17, 6)
+         millisec = timedelta(0, 0, 1000)
+         hour = timedelta(0, 3600)
+         day = timedelta(1)
+         week = timedelta(7)
+         self.assertEqual(a + hour, datetime(2002, 3, 2, 18, 6))
+         self.assertEqual(a + 10*hour, datetime(2002, 3, 3, 3, 6))
+         self.assertEqual(a - hour, datetime(2002, 3, 2, 16, 6))
+         self.assertEqual(a - hour, a + -hour)
+         self.assertEqual(a - 20*hour, datetime(2002, 3, 1, 21, 6))
+         self.assertEqual(a + day, datetime(2002, 3, 3, 17, 6))
+         self.assertEqual(a - day, datetime(2002, 3, 1, 17, 6))
+         self.assertEqual(a + week, datetime(2002, 3, 9, 17, 6))
+         self.assertEqual(a - week, datetime(2002, 2, 23, 17, 6))
+         self.assertEqual(a + 52*week, datetime(2003, 3, 1, 17, 6))
+         self.assertEqual(a - 52*week, datetime(2001, 3, 3, 17, 6))
+         self.assertEqual((a + week) - a, week)
+         self.assertEqual((a + day) - a, day)
+         self.assertEqual((a + hour) - a, hour)
+         self.assertEqual((a + millisec) - a, millisec)
+         self.assertEqual((a - week) - a, -week)
+         self.assertEqual((a - day) - a, -day)
+         self.assertEqual((a - hour) - a, -hour)
+         self.assertEqual((a - millisec) - a, -millisec)
+         self.assertEqual(a - (a + week), -week)
+         self.assertEqual(a - (a + day), -day)
+         self.assertEqual(a - (a + hour), -hour)
+         self.assertEqual(a - (a + millisec), -millisec)
+         self.assertEqual(a - (a - week), week)
+         self.assertEqual(a - (a - day), day)
+         self.assertEqual(a - (a - hour), hour)
+         self.assertEqual(a - (a - millisec), millisec)
+         self.assertEqual(a + (week + day + hour + millisec),
+                          datetime(2002, 3, 10, 18, 6, 0, 1000))
+         self.assertEqual(a + (week + day + hour + millisec),
+                          (((a + week) + day) + hour) + millisec)
+         self.assertEqual(a - (week + day + hour + millisec),
+                          datetime(2002, 2, 22, 16, 5, 59, 999000))
+         self.assertEqual(a - (week + day + hour + millisec),
+                          (((a - week) - day) - hour) - millisec)
  
  def test_suite():