Skip to content

Commit

Permalink
Document behavior when time delta addition falls after end of month
Browse files Browse the repository at this point in the history
Document potentially surprising behaviour and add tests to cover these cases.
  • Loading branch information
Mifrill committed Oct 12, 2021
1 parent 994f366 commit 83ec82c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ switch, and thus all their contributions are dual-licensed.
- Adrien Cossa <cossa@MASKED>
- Alec Nikolas Reiter <alecreiter@MASKED>
- Alec Reiter <areiter@MASKED>
- Aleksei Strizhak <alexei.mifrill.strizhak@MASKED> (gh: @Mifrill)
- Alex Chamberlain (gh: @alexchamberlain) **D**
- Alex Verdyan <verdyan@MASKED>
- Alex Willmer <alex@moreati.org.uk> (gh: @moreati) **R**
Expand Down
3 changes: 3 additions & 0 deletions changelog.d/1167.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added note into docs and tests where relativedelta would return last day of the month
only if the same day on a different month resolves to a date that doesn't exist.
Reported by @hawkEye-01 (gh issue #1167). Fixed by @Mifrill (gh pr #1168)
9 changes: 9 additions & 0 deletions docs/relativedelta.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ boundary.

The logic for years is the same, even on leap years.

If the result falls on a day after the last one of the month, the last day of the month is used instead.

.. doctest::

>>> date(2003,1,30)+relativedelta(months=+1)
datetime.date(2003, 2, 28)
>>> date(2003,5,31)+relativedelta(months=-1)
datetime.date(2003, 4, 30)

.. doctest:: relativedelta

>>> date(2000,2,28)+relativedelta(years=+1)
Expand Down
61 changes: 61 additions & 0 deletions tests/test_relativedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,67 @@ def testHashable(self):
except:
self.fail("relativedelta() failed to hash!")

def testDayOfMonthPlus(self):
assert [
date(2021, 1, 28) + relativedelta(months=1),
date(2021, 2, 27) + relativedelta(months=1),
date(2021, 4, 29) + relativedelta(months=1),
date(2021, 5, 30) + relativedelta(months=1),
] == [
date(2021, 2, 28),
date(2021, 3, 27),
date(2021, 5, 29),
date(2021, 6, 30),
]

def testLastDayOfMonthPlus(self):
assert [
date(2021, 1, 31) + relativedelta(months=1),
date(2021, 1, 30) + relativedelta(months=1),
date(2021, 1, 29) + relativedelta(months=1),
date(2021, 1, 28) + relativedelta(months=1),
date(2021, 2, 28) + relativedelta(months=1),
date(2021, 4, 30) + relativedelta(months=1),
date(2021, 5, 31) + relativedelta(months=1),
] == [
date(2021, 2, 28),
date(2021, 2, 28),
date(2021, 2, 28),
date(2021, 2, 28),
date(2021, 3, 28),
date(2021, 5, 30),
date(2021, 6, 30),
]

def testDayOfMonthMinus(self):
assert [
date(2021, 2, 27) - relativedelta(months=1),
date(2021, 3, 30) - relativedelta(months=1),
date(2021, 3, 29) - relativedelta(months=1),
date(2021, 3, 28) - relativedelta(months=1),
date(2021, 5, 30) - relativedelta(months=1),
date(2021, 6, 29) - relativedelta(months=1),
] == [
date(2021, 1, 27),
date(2021, 2, 28),
date(2021, 2, 28),
date(2021, 2, 28),
date(2021, 4, 30),
date(2021, 5, 29),
]

def testLastDayOfMonthMinus(self):
assert [
date(2021, 2, 28) - relativedelta(months=1),
date(2021, 3, 31) - relativedelta(months=1),
date(2021, 5, 31) - relativedelta(months=1),
date(2021, 6, 30) - relativedelta(months=1),
] == [
date(2021, 1, 28),
date(2021, 2, 28),
date(2021, 4, 30),
date(2021, 5, 30),
]

class RelativeDeltaWeeksPropertyGetterTest(unittest.TestCase):
"""Test the weeks property getter"""
Expand Down

0 comments on commit 83ec82c

Please sign in to comment.