[Python-checkins] CVS: python/nondist/sandbox/datetime datetime.py,1.55,1.56 test_datetime.py,1.39,1.40

Guido van Rossum gvanrossum@users.sourceforge.net
Mon, 18 Mar 2002 15:06:32 -0800


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

Modified Files:
	datetime.py test_datetime.py 
Log Message:
Add datetimetz type.  Add unittests for it that make sure it behaves
just like datetime when tzinfo=None.  XXX Unittests for other tzinfo
values are still missing.



Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.55
retrieving revision 1.56
diff -C2 -d -r1.55 -r1.56
*** datetime.py	6 Mar 2002 04:10:37 -0000	1.55
--- datetime.py	18 Mar 2002 23:06:30 -0000	1.56
***************
*** 933,936 ****
--- 933,1022 ----
  
  
+ class datetimetz(datetime):
+ 
+     def __init__(self, year, month, day, hour=0, minute=0, second=0,
+                  microsecond=0, tzinfo=None):
+         super(datetimetz, self).__init__(year, month, day,
+                                          hour, minute, second, microsecond)
+         if tzinfo is not None:
+             # Better fail now than later
+             assert hasattr(tzinfo, 'utcoffset')
+             assert hasattr(tzinfo, 'dst')
+             assert hasattr(tzinfo, 'tzname')
+         self.__tzinfo = tzinfo
+ 
+     def __hash__(self):
+         tz = self.__tzinfo
+         if tz == None:
+             return super(datetime, self).__hash__()
+         tzoff = tz.utcoffset(self)
+         if not tzoff: # zero or None!
+             return super(datetime, self).__hash__()
+         t = self - timedelta(minutes=tzoff)
+         return super(datetime, t).__hash__()
+ 
+     def __add__(self, other):
+         result = super(datetimetz, self).__add__(other)
+         assert isinstance(result, datetimetz)
+         result.__tzinfo = self.__tzinfo
+         return result
+ 
+     __radd__ = __add__
+ 
+     def __sub__(self, other):
+         supersub = super(datetimetz, self).__sub__
+         if not isinstance(other, datetime):
+             return supersub(other)
+         mytz = self.__tzinfo
+         ottz = None
+         if isinstance(other, datetimetz):
+             ottz = other.__tzinfo
+         if mytz == ottz:
+             return supersub(other)
+         myoff = otoff = None
+         if self.__tzinfo is not None:
+             myoff = self.__tzinfo.utcoffset(self)
+         if isinstance(other, datetimetz) and other.__tzinfo is not None:
+             otoff = other.__tzinfo.utcoffset(other)
+         if myoff == otoff:
+             return supersub(other)
+         if myoff is None or otoff is None:
+             raise ValueError, "cannot mix naive and timezone-aware time"
+         return supersub(other) + timedelta(minutes=otoff-myoff)
+ 
+     def __cmp__(self, other):
+         if not isinstance(other, datetime):
+             raise TypeError("can't compare datetime to %s instance" %
+                             type(other).__name__)
+         superself = super(datetimetz, self)
+         supercmp = superself.__cmp__
+         mytz = self.__tzinfo
+         ottz = None
+         if isinstance(other, datetimetz):
+             ottz = other.__tzinfo
+         if mytz == ottz:
+             return supercmp(other)
+         myoff = otoff = None
+         if mytz is not None:
+             myoff = mytz.utcoffset(self)
+         if ottz is not None:
+             otoff = ottz.utcoffset(other)
+         if myoff == otoff:
+             return supercmp(other)
+         if myoff is None or otoff is None:
+             raise ValueError, "cannot mix naive and timezone-aware time"
+         diff = superself.__sub__(other) + timedelta(minutes=otoff-myoff)
+         if diff.days < 0:
+             return -1
+         if diff == timedelta():
+             return 1
+         return 1
+ 
+ 
+ datetimetz.min = datetimetz(1, 1, 1)
+ datetimetz.max = datetimetz(9999, 12, 31, 23, 59, 59, 999999)
+ datetimetz.resolution = timedelta(microseconds=1)
+ 
+ 
  def _isoweek1monday(year):
      # Helper to calculate the day number of the Monday starting week 1

Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.39
retrieving revision 1.40
diff -C2 -d -r1.39 -r1.40
*** test_datetime.py	6 Mar 2002 04:37:30 -0000	1.39
--- test_datetime.py	18 Mar 2002 23:06:30 -0000	1.40
***************
*** 7,11 ****
  import unittest
  
! from datetime import date, datetime, timedelta, MINYEAR, MAXYEAR
  
  
--- 7,11 ----
  import unittest
  
! from datetime import date, datetime, datetimetz, timedelta, MINYEAR, MAXYEAR
  
  
***************
*** 517,525 ****
  
  
  def test_suite():
      s1 = unittest.makeSuite(TestTimeDelta, 'test')
      s2 = unittest.makeSuite(TestDate, 'test')
      s3 = unittest.makeSuite(TestDateTime, 'test')
!     return unittest.TestSuite([s1, s2, s3])
  
  def test_main():
--- 517,531 ----
  
  
+ class TestDateTimeTZ(TestDateTime):
+ 
+     theclass = datetimetz
+ 
+ 
  def test_suite():
      s1 = unittest.makeSuite(TestTimeDelta, 'test')
      s2 = unittest.makeSuite(TestDate, 'test')
      s3 = unittest.makeSuite(TestDateTime, 'test')
!     s4 = unittest.makeSuite(TestDateTimeTZ, 'test')
!     return unittest.TestSuite([s1, s2, s3, s4])
  
  def test_main():