Commit 160cf1b2 authored by user's avatar user

Better handling of relative months and years

- Increment months strictly: 01.01.2015 + 1m = 01.02.2015.
- If there are fewer days in target month, date is rounded down:
  31.10.2015 + 1m = 30.11.2015.
- Years are incremented as 12 months.
- Leap years are 366 days long: 01.03.2015 + 1y = 01.03.2016 (not
  29.02.2016 as it would have been if year was equal to 365d)
parent a4427f95
...@@ -17,8 +17,16 @@ ...@@ -17,8 +17,16 @@
""" 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(sourcedate, months):
month = sourcedate.month - 1 + months
year = sourcedate.year + month / 12
month = month % 12 + 1
day = min(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 +41,9 @@ def _convert_pattern(p_length, p_periodunit, p_offset=date.today()): ...@@ -33,11 +41,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