diff --git a/CHANGES.rst b/CHANGES.rst index bac3d1a5..5e64c10d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,7 @@ Changelog Minor changes: -- ... +- Adjusted duration regex Breaking changes: diff --git a/docs/credits.rst b/docs/credits.rst index 0623611d..1cf1df80 100644 --- a/docs/credits.rst +++ b/docs/credits.rst @@ -67,6 +67,7 @@ icalendar contributors - Pronoy - Abe Hanoka - `Natasha Mattson `_ Find out who contributed:: diff --git a/src/icalendar/prop.py b/src/icalendar/prop.py index ac87d0ba..7ee13468 100644 --- a/src/icalendar/prop.py +++ b/src/icalendar/prop.py @@ -63,12 +63,9 @@ import time as _time -DATE_PART = r'(\d+)D' -TIME_PART = r'T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?' -DATETIME_PART = f'(?:{DATE_PART})?(?:{TIME_PART})?' -WEEKS_PART = r'(\d+)W' -DURATION_REGEX = re.compile(r'([-+]?)P(?:%s|%s)$' - % (WEEKS_PART, DATETIME_PART)) +DURATION_REGEX = re.compile(r'([-+]?)P(?:(\d+)W)?(?:(\d+)D)?' + r'(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$') + WEEKDAY_RULE = re.compile(r'(?P[+-]?)(?P[\d]?)' r'(?P[\w]{2})$') @@ -475,22 +472,24 @@ def to_ical(self): @staticmethod def from_ical(ical): - try: - match = DURATION_REGEX.match(ical) - sign, weeks, days, hours, minutes, seconds = match.groups() - if weeks: - value = timedelta(weeks=int(weeks)) - else: - value = timedelta(days=int(days or 0), - hours=int(hours or 0), - minutes=int(minutes or 0), - seconds=int(seconds or 0)) - if sign == '-': - value = -value - return value - except Exception: + match = DURATION_REGEX.match(ical) + if not match: raise ValueError(f'Invalid iCalendar duration: {ical}') + sign, weeks, days, hours, minutes, seconds = match.groups() + value = timedelta( + weeks=int(weeks or 0), + days=int(days or 0), + hours=int(hours or 0), + minutes=int(minutes or 0), + seconds=int(seconds or 0) + ) + + if sign == '-': + value = -value + + return value + class vPeriod: """A precise period of time.