Code

Oops, there's 24 hours in a day, and subtraction of intervals now works
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Thu, 21 Feb 2002 23:34:52 +0000 (23:34 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Thu, 21 Feb 2002 23:34:52 +0000 (23:34 +0000)
properly.

git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@653 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/date.py
test/test_dates.py

index c707e6830d96f408149720c8dbea582fb9159293..c170fb6b3ac3c61c5f2921ce8fc984cf47b572aa 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: date.py,v 1.19 2002-02-21 23:11:45 richard Exp $
+# $Id: date.py,v 1.20 2002-02-21 23:34:51 richard Exp $
 
 __doc__ = """
 Date, time and time interval handling.
@@ -123,8 +123,8 @@ class Date:
             elif second > 59: minute += 1; second -= 60
             if minute < 0: hour -= 1; minute += 60
             elif minute > 59: hour += 1; minute -= 60
-            if hour < 0: day -= 1; hour += 60
-            elif hour > 59: day += 1; hour -= 60
+            if hour < 0: day -= 1; hour += 24
+            elif hour > 59: day += 1; hour -= 24
 
         # fix up the month so we're within range
         while month < 1 or month > 12:
@@ -157,31 +157,35 @@ class Date:
              1. an interval from this date to produce another date.
              2. a date from this date to produce an interval.
         """
-        if isinstance(other, Date):
-            # TODO this code will fall over laughing if the dates cross
-            # leap years, phases of the moon, ....
-            a = calendar.timegm((self.year, self.month, self.day, self.hour,
-                self.minute, self.second, 0, 0, 0))
-            b = calendar.timegm((other.year, other.month, other.day,
-                other.hour, other.minute, other.second, 0, 0, 0))
-            diff = a - b
-            if diff < 0:
-                sign = 1
-                diff = -diff
-            else:
-                sign = -1
-            S = diff%60
-            M = (diff/60)%60
-            H = (diff/(60*60))%60
-            if H>1: S = 0
-            d = (diff/(24*60*60))%30
-            if d>1: H = S = M = 0
-            m = (diff/(30*24*60*60))%12
-            if m>1: H = S = M = 0
-            y = (diff/(365*24*60*60))
-            if y>1: d = H = S = M = 0
-            return Interval((y, m, d, H, M, S), sign=sign)
-        return self.__add__(other)
+        if isinstance(other, Interval):
+            other = Interval(other.get_tuple(), sign=-other.sign)
+            return self.__add__(other)
+
+        assert isinstance(other, Date), 'May only subtract Dates or Intervals'
+
+        # TODO this code will fall over laughing if the dates cross
+        # leap years, phases of the moon, ....
+        a = calendar.timegm((self.year, self.month, self.day, self.hour,
+            self.minute, self.second, 0, 0, 0))
+        b = calendar.timegm((other.year, other.month, other.day,
+            other.hour, other.minute, other.second, 0, 0, 0))
+        diff = a - b
+        if diff < 0:
+            sign = 1
+            diff = -diff
+        else:
+            sign = -1
+        S = diff%60
+        M = (diff/60)%60
+        H = (diff/(60*60))%60
+        if H>1: S = 0
+        d = (diff/(24*60*60))%30
+        if d>1: H = S = M = 0
+        m = (diff/(30*24*60*60))%12
+        if m>1: H = S = M = 0
+        y = (diff/(365*24*60*60))
+        if y>1: d = H = S = M = 0
+        return Interval((y, m, d, H, M, S), sign=sign)
 
     def __cmp__(self, other):
         """Compare this date to another date."""
@@ -433,6 +437,11 @@ if __name__ == '__main__':
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.19  2002/02/21 23:11:45  richard
+#  . fixed some problems in date calculations (calendar.py doesn't handle over-
+#    and under-flow). Also, hour/minute/second intervals may now be more than
+#    99 each.
+#
 # Revision 1.18  2002/01/23 20:00:50  jhermann
 # %e is a UNIXism and not documented for Python
 #
index 6b04d518508b63eb0ee5d25b9fcc2bf7d54b2880..14da7ec56adbd0cac24b0b85e91fb2d2bf36d403 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: test_dates.py,v 1.10 2002-02-21 23:11:45 richard Exp $ 
+# $Id: test_dates.py,v 1.11 2002-02-21 23:34:52 richard Exp $ 
 
 import unittest, time
 
@@ -74,7 +74,7 @@ class DateTestCase(unittest.TestCase):
         # now check calculations
         date = Date('2000-01-01') + Interval('- 2y 2m')
         ae(str(date), '1997-11-01.00:00:00')
-        date = Date('2000-01-01') + Interval('2m')
+        date = Date('2000-01-01') + Interval('2m')
         ae(str(date), '2000-03-01.00:00:00')
 
         date = Date('2000-01-01') + Interval('60d')
@@ -82,6 +82,7 @@ class DateTestCase(unittest.TestCase):
         date = Date('2001-01-01') + Interval('60d')
         ae(str(date), '2001-03-02.00:00:00')
 
+        # time additions
         date = Date('2000-02-28.23:59:59') + Interval('00:00:01')
         ae(str(date), '2000-02-29.00:00:00')
         date = Date('2001-02-28.23:59:59') + Interval('00:00:01')
@@ -102,6 +103,37 @@ class DateTestCase(unittest.TestCase):
         date = Date('2001-02-28.22:58:59') + Interval('00:00:3661')
         ae(str(date), '2001-03-01.00:00:00')
 
+        # now subtractions
+        date = Date('2000-01-01') - Interval('- 2y 2m')
+        ae(str(date), '2002-03-01.00:00:00')
+        date = Date('2000-01-01') - Interval('2m')
+        ae(str(date), '1999-11-01.00:00:00')
+
+        date = Date('2000-03-01') - Interval('60d')
+        ae(str(date), '2000-01-01.00:00:00')
+        date = Date('2001-03-02') - Interval('60d')
+        ae(str(date), '2001-01-01.00:00:00')
+
+        date = Date('2000-02-29.00:00:00') - Interval('00:00:01')
+        ae(str(date), '2000-02-28.23:59:59')
+        date = Date('2001-03-01.00:00:00') - Interval('00:00:01')
+        ae(str(date), '2001-02-28.23:59:59')
+
+        date = Date('2000-02-29.00:00:00') - Interval('00:01:01')
+        ae(str(date), '2000-02-28.23:58:59')
+        date = Date('2001-03-01.00:00:00') - Interval('00:01:01')
+        ae(str(date), '2001-02-28.23:58:59')
+
+        date = Date('2000-02-29.00:00:00') - Interval('01:01:01')
+        ae(str(date), '2000-02-28.22:58:59')
+        date = Date('2001-03-01.00:00:00') - Interval('01:01:01')
+        ae(str(date), '2001-02-28.22:58:59')
+
+        date = Date('2000-02-29.00:00:00') - Interval('00:00:3661')
+        ae(str(date), '2000-02-28.22:58:59')
+        date = Date('2001-03-01.00:00:00') - Interval('00:00:3661')
+        ae(str(date), '2001-02-28.22:58:59')
+
     def testInterval(self):
         ae = self.assertEqual
         ae(str(Interval('3y')), '+ 3y')
@@ -118,6 +150,11 @@ def suite():
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.10  2002/02/21 23:11:45  richard
+#  . fixed some problems in date calculations (calendar.py doesn't handle over-
+#    and under-flow). Also, hour/minute/second intervals may now be more than
+#    99 each.
+#
 # Revision 1.9  2002/02/21 06:57:39  richard
 #  . Added popup help for classes using the classhelp html template function.
 #    - add <display call="classhelp('priority', 'id,name,description')">