Commit 25dd79b5 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge pull request #115 from mruwek/business_days

Add recurrence and postponing by business days
parents 314b21a1 c02e997f
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from datetime import date, timedelta from datetime import date
from freezegun import freeze_time from freezegun import freeze_time
from test.topydo_testcase import TopydoTest from test.topydo_testcase import TopydoTest
...@@ -40,6 +40,18 @@ class RelativeDateTester(TopydoTest): ...@@ -40,6 +40,18 @@ class RelativeDateTester(TopydoTest):
result = relative_date_to_date('1d') result = relative_date_to_date('1d')
self.assertEqual(result, self.tomorrow) self.assertEqual(result, self.tomorrow)
def test_zero_bdays(self):
result = relative_date_to_date('0b')
self.assertEqual(result, self.today)
def test_one_bday(self):
result = relative_date_to_date('1b')
self.assertEqual(result, self.monday)
def test_one_bweek(self):
result = relative_date_to_date('5b')
self.assertEqual(result, self.friday)
def test_one_week(self): def test_one_week(self):
result = relative_date_to_date('1w') result = relative_date_to_date('1w')
self.assertEqual(result, date(2015, 11, 13)) self.assertEqual(result, date(2015, 11, 13))
...@@ -152,6 +164,14 @@ class RelativeDateTester(TopydoTest): ...@@ -152,6 +164,14 @@ class RelativeDateTester(TopydoTest):
result = relative_date_to_date('-0d') result = relative_date_to_date('-0d')
self.assertTrue(result, self.today) self.assertTrue(result, self.today)
def test_negative_period3(self):
result = relative_date_to_date('-1b')
self.assertEqual(result, date(2015, 11, 5))
def test_negative_period4(self):
result = relative_date_to_date('-5b')
self.assertEqual(result, date(2015, 10, 30))
def test_weekday_next_week(self): def test_weekday_next_week(self):
""" """
When entering "Friday" on a Friday, return next week Friday instead of When entering "Friday" on a Friday, return next week Friday instead of
......
...@@ -37,9 +37,26 @@ def _add_months(p_sourcedate, p_months): ...@@ -37,9 +37,26 @@ def _add_months(p_sourcedate, p_months):
return date(year, month, day) return date(year, month, day)
def _add_business_days(p_sourcedate, p_bdays):
""" Adds a number of business days to the source date. """
result = p_sourcedate
delta = 1 if p_bdays > 0 else -1
while abs(p_bdays) > 0:
result += timedelta(delta)
weekday = result.weekday()
if weekday >= 5:
continue
p_bdays = p_bdays - 1 if delta > 0 else p_bdays + 1
return result
def _convert_pattern(p_length, p_periodunit, p_offset=None): def _convert_pattern(p_length, p_periodunit, p_offset=None):
""" """
Converts a pattern in the form [0-9][dwmy] and returns a date from the Converts a pattern in the form [0-9][dwmyb] and returns a date from the
offset with the period of time added to it. offset with the period of time added to it.
""" """
result = None result = None
...@@ -55,6 +72,8 @@ def _convert_pattern(p_length, p_periodunit, p_offset=None): ...@@ -55,6 +72,8 @@ def _convert_pattern(p_length, p_periodunit, p_offset=None):
result = _add_months(p_offset, p_length) result = _add_months(p_offset, p_length)
elif p_periodunit == 'y': elif p_periodunit == 'y':
result = _add_months(p_offset, p_length * 12) result = _add_months(p_offset, p_length * 12)
elif p_periodunit == 'b':
result = _add_business_days(p_offset, p_length)
return result return result
...@@ -98,7 +117,8 @@ def relative_date_to_date(p_date, p_offset=None): ...@@ -98,7 +117,8 @@ def relative_date_to_date(p_date, p_offset=None):
p_date = p_date.lower() p_date = p_date.lower()
p_offset = p_offset or date.today() p_offset = p_offset or date.today()
relative = re.match('(?P<length>-?[0-9]+)(?P<period>[dwmy])$', p_date, re.I) relative = re.match('(?P<length>-?[0-9]+)(?P<period>[dwmyb])$',
p_date, re.I)
monday = 'mo(n(day)?)?$' monday = 'mo(n(day)?)?$'
tuesday = 'tu(e(sday)?)?$' tuesday = 'tu(e(sday)?)?$'
......
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