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:
parent
3cb7f74e1c
commit
6ad3a48d64
@ -1,3 +1,7 @@
|
||||
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
|
||||
|
||||
2008-02-15 Gary Burton <gary.burton@zen.co.uk>
|
||||
* src/DataViews/RelationView.py:
|
||||
* src/Editors/_EditFamily.py: prevent right mouse button causing crash.
|
||||
|
@ -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]:
|
||||
@ -275,12 +282,33 @@ class Date:
|
||||
if months > 12:
|
||||
years += months / 12
|
||||
months = months % 12
|
||||
# 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)
|
||||
elif type(other) in [tuple, list]:
|
||||
return self.copy_offset_ymd(*map(lambda x: -x, other))
|
||||
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:
|
||||
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
|
||||
|
@ -135,5 +135,65 @@ def suite():
|
||||
count += 1
|
||||
return suite
|
||||
|
||||
def assert_func(exp1, exp2):
|
||||
Date = date.Date
|
||||
e1 = eval(exp1)
|
||||
e2 = eval(exp2)
|
||||
assert e1 == e2, "%s should be %s but was %s" % (exp1, e2, e1)
|
||||
|
||||
class Assert(unittest.TestCase):
|
||||
def __init__(self, method_name, part, exp1, exp2):
|
||||
self.__dict__[method_name + ("-%d" % part)] = \
|
||||
lambda: assert_func(exp1, exp2)
|
||||
unittest.TestCase.__init__(self, method_name + ("-%d" % part))
|
||||
|
||||
def suite2():
|
||||
""" interface to automated test runner test/regrtest.py """
|
||||
Config.set(Config.DATE_BEFORE_RANGE, 9999)
|
||||
Config.set(Config.DATE_AFTER_RANGE, 9999)
|
||||
Config.set(Config.DATE_ABOUT_RANGE, 10)
|
||||
tests = [
|
||||
# Date +/- int/tuple -> Date
|
||||
("Date(2008, 1, 1) - 1", "Date(2007, 1, 1)"),
|
||||
("Date(2008, 1, 1) + 1", "Date(2009, 1, 1)"),
|
||||
("Date(2008, 1, 1) - (0,0,1)", "Date(2007, 12, 31)"),
|
||||
("Date(2008, 1, 1) - (0,0,2)", "Date(2007, 12, 30)"),
|
||||
("Date(2008) - (0,0,1)", "Date(2007, 12, 31)"),
|
||||
("Date(2008) - 1", "Date(2007, 1, 1)"),
|
||||
("Date(2008, 12, 31) + (0, 0, 1)", "Date(2009, 1, 1)"),
|
||||
("Date(2000,1,1) - (0,11,0)", "Date(1999,02,01)"),
|
||||
("Date(2000,1,1) - (0,1,0)", "Date(1999, 12, 1)"),
|
||||
("Date(2008, 1, 1) + (0, 0, 32)", "Date(2008, 02, 02)"),
|
||||
("Date(2008, 2, 1) + (0, 0, 32)", "Date(2008, 03, 04)"),
|
||||
("Date(2000) - (0, 1, 0)", "Date(1999, 12, 1)"),
|
||||
("Date(2000) + (0, 1, 0)", "Date(2000, 1, 0)"), # Ok?
|
||||
("Date(2000, 1, 1) - (0, 1, 0)", "Date(1999, 12, 1)"),
|
||||
("Date(2000, 1, 1) - 1", "Date(1999, 1, 1)"),
|
||||
("Date(2000) - 1", "Date(1999)"),
|
||||
("Date(2000) + 1", "Date(2001)"),
|
||||
|
||||
#My great great grandfather died on 1876-05-07.
|
||||
#He died at an age of 65 years, 5 month 17 days according to the books:
|
||||
#> Date(1876,5,7)-(65,5,17)
|
||||
#1811-12-21
|
||||
#> Date(1876,5,7)-Date(1811,12,21)
|
||||
#(64, 4, 17)
|
||||
#But his correct birth date is 1810-11-20:
|
||||
#("Date(1876,5,7)-Date(1810,11,20)", "(65, 5, 18)")
|
||||
("Date(1876,5,7) - Date(1876,5,1)", "(0, 0, 6)"),
|
||||
("Date(1876,5,7) - Date(1876,4,30)", "(0, 0, 7)"),
|
||||
("Date(2000,1,1) - Date(1999,2,1)", "(0, 11, 0)"),
|
||||
("Date(2000,1,1) - Date(1999,12,1)", "(0, 1, 0)"),
|
||||
# Date +/- Date -> tuple
|
||||
("Date(2007, 12, 23) - Date(1963, 12, 4)", "(44, 0, 19)"),
|
||||
]
|
||||
suite = unittest.TestSuite()
|
||||
count = 1
|
||||
for (exp1, exp2) in tests:
|
||||
suite.addTest(Assert('test_assert%04d' % count, 1, exp1, exp2))
|
||||
count += 1
|
||||
return suite
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.TextTestRunner().run(suite())
|
||||
unittest.TextTestRunner().run(suite2())
|
||||
|
Loading…
Reference in New Issue
Block a user