diff options
Diffstat (limited to 'odoo/tools/date_utils.py')
| -rw-r--r-- | odoo/tools/date_utils.py | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/odoo/tools/date_utils.py b/odoo/tools/date_utils.py index e7d1aa24ffd..55220ced033 100644 --- a/odoo/tools/date_utils.py +++ b/odoo/tools/date_utils.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- - import math import calendar from datetime import date, datetime, time - +import pytz from dateutil.relativedelta import relativedelta from . import ustr @@ -178,3 +177,43 @@ def json_default(obj): return fields.Datetime.to_string(obj) return fields.Date.to_string(obj) return ustr(obj) + +def date_range(start, end, step=relativedelta(months=1)): + """Date range generator with a step interval. + + :param start datetime: begining date of the range. + :param end datetime: ending date of the range. + :param step relativedelta: interval of the range. + :return: a range of datetime from start to end. + :rtype: Iterator[datetime] + """ + + are_naive = start.tzinfo is None and end.tzinfo is None + are_utc = start.tzinfo == pytz.utc and end.tzinfo == pytz.utc + + # Cases with miscellenous timezone are more complexe because of DST. + are_others = start.tzinfo and end.tzinfo and not are_utc + + if are_others: + if start.tzinfo.zone != end.tzinfo.zone: + raise ValueError("Timezones of start argument and end argument seem inconsistent") + + if not are_naive and not are_utc and not are_others: + raise ValueError("Timezones of start argument and end argument mismatch") + + if start > end: + raise ValueError("start > end, start date must be before end") + + if start == start + step: + raise ValueError("Looks like step is null") + + if start.tzinfo: + localize = start.tzinfo.localize + else: + localize = lambda dt: dt + + dt = start.replace(tzinfo=None) + end = end.replace(tzinfo=None) + while dt <= end: + yield localize(dt) + dt = dt + step |
