Roundup Tracker - Issues

Issue 2550858

classification
Title: Month intervals at the end of long months yield the wrong day
Type: behavior Severity: normal
Components: Infrastructure Versions: devel, 1.5, 1.4, 1.3
process
Status: new Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ThomasAH, ber
Priority: normal Keywords:

Created on 2014-10-31 15:40 by ThomasAH, last changed 2014-12-11 09:00 by ber.

Messages
msg5156 Author: [hidden] (ThomasAH) Date: 2014-10-31 15:40
Tested in the current devel version, but I assume it affects all
previous versions, too:

>>> from roundup import date
>>> date.Date("2014-10-31 +1m")
<Date 2014-12-01.00:00:00.000>
This should yield 2014-11-30

>>> date.Date("2014-10-31 -1m")
<Date 2014-10-01.00:00:00.000>
This should yield 2014-09-30

This affects at least the popup calender and searching for date ranges.

The culprit is the following code from roundup.date.Date addInterval():

    while month < 1 or month > 12 or day < 1 or day > get_mdays(year,month):
        # now to day under/over
        if day < 1:
            # When going backwards, decrement month, then increment days
            month -= 1
            day += get_mdays(year,month)
        elif day > get_mdays(year,month):
            # When going forwards, decrement days, then increment month
            day -= get_mdays(year,month)
            month += 1

        # possibly fix up the month so we're within range
        while month < 1 or month > 12:
            if month < 1: year -= 1; month += 12 ; day += 31
            if month > 12: year += 1; month -= 12

Reproducible by running "./run_tests.py test_dates.py" after applying the
following patch:

diff -r b76710818d31 test/test_dates.py
--- a/test/test_dates.py	Mon Oct 20 14:10:32 2014 -0400
+++ b/test/test_dates.py	Fri Oct 31 16:35:41 2014 +0100
@@ -122,6 +122,19 @@
         date = Date('2000-01-01 + 2m')
         ae(str(date), '2000-03-01.00:00:00')
 
+        date = Date('2000-01-29 + 1m')
+        ae(str(date), '2000-02-29.00:00:00')
+        date = Date('2001-01-29 + 1m')
+        ae(str(date), '2000-02-28.00:00:00')
+        date = Date('2001-01-30 + 1m')
+        ae(str(date), '2000-02-28.00:00:00')
+        date = Date('2000-10-31 + 1m')
+        ae(str(date), '2000-11-30.00:00:00')
+        date = Date('2000-10-31 - 1m')
+        ae(str(date), '2000-09-30.00:00:00')
+        date = Date('2000-03-31 - 1m')
+        ae(str(date), '2000-02-29.00:00:00')
+
         date = Date('2000-01-01') + Interval('60d')
         ae(str(date), '2000-03-01.00:00:00')
         date = Date('2001-01-01') + Interval('60d')
History
Date User Action Args
2014-12-11 09:00:39bersetnosy: + ber
2014-10-31 15:40:52ThomasAHcreate