2008-02-17 Douglas S. Blank <dblank@cs.brynmawr.edu>

* src/gen/lib/date.py (Date.__sub__): fixed some date math (#1649)
	* src/gen/lib/test/date_test.py: added some unit tests for date math



svn: r10043
This commit is contained in:
Doug Blank
2008-02-17 17:53:43 +00:00
parent 3cb7f74e1c
commit 6ad3a48d64
3 changed files with 108 additions and 10 deletions

View File

@@ -246,13 +246,20 @@ class Date:
"""
Date artithmetic: Date() - years, Date - (y,m,d), or Date() - Date()
"""
if type(other) == int:
if type(other) == int: # Date - value -> Date
return self.copy_offset_ymd(-other)
elif type(other) == type(self): # date
elif type(other) in [tuple, list]: # Date - (y, m, d) -> Date
return self.copy_offset_ymd(*map(lambda x: -x, other))
elif type(other) == type(self): # Date1 - Date2 -> tuple
# We should make sure that Date2 + tuple -> Date1 and
# Date1 - tuple -> Date2
d1 = map(lambda i: i or 1, self.get_ymd())
d2 = map(lambda i: i or 1, other.get_ymd())
date1 = self
date2 = other
if d1 < d2:
d1, d2 = d2, d1
date1, date2 = date2, date1
# d1 - d2 (1998, 12, 32) - (1982, 12, 15) =
# days:
if d2[2] > d1[2]:
@@ -269,18 +276,39 @@ class Date:
days = d1[2] - d2[2]
months = d1[1] - d2[1]
years = d1[0] - d2[0]
if days > 31:
if days > 31:
months += days / 31
days = days % 31
if months > 12:
years += months / 12
months = months % 12
return (years, months, days)
elif type(other) in [tuple, list]:
return self.copy_offset_ymd(*map(lambda x: -x, other))
# estimate: (years, months, days)
# Check transitivity:
eDate = date1 - (years, months, days)
if eDate < date2: # too small
diff = 0
while eDate < date2 and diff < 60:
diff += 1
eDate = eDate + (0, 0, diff)
if diff == 60:
return (0, 0, 0)
return (years, months, days - diff)
elif eDate > date2:
diff = 0
while eDate > date2 and diff > -60:
diff -= 1
eDate = eDate - (0, 0, abs(diff))
if diff == -60:
return (0, 0, 0)
return (years, months, days + diff)
else:
return (years, months, days)
else:
raise AttributeError, "unknown date sub type: %s " % type(other)
def __eq__(self, other):
return self.sortval == other.sortval
def __lt__(self, other):
return self.sortval < other.sortval
@@ -629,12 +657,18 @@ class Date:
if dv[Date._POS_MON]:
dv[Date._POS_MON] += month
elif month:
dv[Date._POS_MON] = month
if month < 0:
dv[Date._POS_MON] = 1 + month
else:
dv[Date._POS_MON] = month
# Fix if month out of bounds:
if month != 0: # only check if changed
if dv[Date._POS_MON] <= 0: # subtraction
dv[Date._POS_YR] -= int(-dv[Date._POS_MON] / 12)
dv[Date._POS_MON] = 13 - dv[Date._POS_MON] % 12
if dv[Date._POS_MON] == 0: # subtraction
dv[Date._POS_MON] = 12
dv[Date._POS_YR] -= 1
elif dv[Date._POS_MON] < 0: # subtraction
dv[Date._POS_YR] -= int((-dv[Date._POS_MON]) / 12) + 1
dv[Date._POS_MON] = (dv[Date._POS_MON] % 12)
elif dv[Date._POS_MON] > 12 or dv[Date._POS_MON] < 1:
dv[Date._POS_YR] += int(dv[Date._POS_MON] / 12)
dv[Date._POS_MON] = dv[Date._POS_MON] % 12