Commit 5c350269 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge branch 'mruwek-fixRelativeDates2'

parents 8f1153a0 df53f811
...@@ -43,12 +43,40 @@ class RelativeDateTester(TopydoTest.TopydoTest): ...@@ -43,12 +43,40 @@ class RelativeDateTester(TopydoTest.TopydoTest):
self.assertEquals(result, date.today() + timedelta(weeks=1)) self.assertEquals(result, date.today() + timedelta(weeks=1))
def test_one_month(self): def test_one_month(self):
result = relative_date_to_date('1m') test_date = date(2015, 1, 10)
self.assertEquals(result, date.today() + timedelta(30)) result = relative_date_to_date('1m', test_date)
self.assertEquals(result, date(2015, 2, 10))
def test_one_month_ext(self):
test_date1 = date(2015, 1, 29)
test_date2 = date(2016, 1, 31)
test_date3 = date(2015, 12, 31)
test_date4 = date(2015, 7, 31)
test_date5 = date(2015, 10, 31)
result1 = relative_date_to_date('1m', test_date1)
result2 = relative_date_to_date('1m', test_date2)
result3 = relative_date_to_date('1m', test_date3)
result4 = relative_date_to_date('1m', test_date4)
result5 = relative_date_to_date('1m', test_date5)
self.assertEquals(result1, date(2015, 2, 28))
self.assertEquals(result2, date(2016, 2, 29))
self.assertEquals(result3, date(2016, 1, 31))
self.assertEquals(result4, date(2015, 8, 31))
self.assertEquals(result5, date(2015, 11, 30))
def test_one_year(self): def test_one_year(self):
result = relative_date_to_date('1y') test_date = date(2015, 1, 10)
self.assertEquals(result, date.today() + timedelta(365)) result = relative_date_to_date('1y', test_date)
self.assertEquals(result, date(2016, 1, 10))
def test_leap_year(self):
test_date = date(2016, 2, 29)
result1 = relative_date_to_date('1y', test_date)
result2 = relative_date_to_date('4y', test_date)
self.assertEquals(result1, date(2017, 2, 28))
self.assertEquals(result2, date(2020, 2, 29))
def test_zero_months(self): def test_zero_months(self):
result = relative_date_to_date('0m') result = relative_date_to_date('0m')
......
...@@ -17,8 +17,24 @@ ...@@ -17,8 +17,24 @@
""" This module deals with relative dates (2d, 5y, Monday, today, etc.) """ """ This module deals with relative dates (2d, 5y, Monday, today, etc.) """
from datetime import date, timedelta from datetime import date, timedelta
import calendar
import re import re
def _add_months(p_sourcedate, p_months):
"""
Adds a number of months to the source date.
Takes into account shorter months and leap years and such.
https://stackoverflow.com/questions/4130922/how-to-increment-datetime-month-in-python
"""
month = p_sourcedate.month - 1 + p_months
year = p_sourcedate.year + month / 12
month = month % 12 + 1
day = min(p_sourcedate.day, calendar.monthrange(year, month)[1])
return date(year, month, day)
def _convert_pattern(p_length, p_periodunit, p_offset=date.today()): def _convert_pattern(p_length, p_periodunit, p_offset=date.today()):
""" """
Converts a pattern in the form [0-9][dwmy] and returns a date from today Converts a pattern in the form [0-9][dwmy] and returns a date from today
...@@ -33,11 +49,9 @@ def _convert_pattern(p_length, p_periodunit, p_offset=date.today()): ...@@ -33,11 +49,9 @@ def _convert_pattern(p_length, p_periodunit, p_offset=date.today()):
elif p_periodunit == 'w': elif p_periodunit == 'w':
result = p_offset + timedelta(weeks=p_length) result = p_offset + timedelta(weeks=p_length)
elif p_periodunit == 'm': elif p_periodunit == 'm':
# we'll consider a month to be 30 days result = _add_months(p_offset, p_length)
result = p_offset + timedelta(30 * p_length)
elif p_periodunit == 'y': elif p_periodunit == 'y':
# we'll consider a year to be 365 days (yeah, I'm aware of leap years) result = _add_months(p_offset, p_length * 12)
result = p_offset + timedelta(365 * p_length)
return result return result
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment