Parsing an ISO8601 duration for an interval

This commit is contained in:
Mat Munn
2018-03-21 11:23:22 +11:00
parent 00d174c9e2
commit 5458b0bf15
2 changed files with 47 additions and 3 deletions
+27 -3
View File
@@ -12,12 +12,14 @@ import time
import functools
from datetime import timedelta, datetime as Datetime
import re
import pytz
import humanize
import dateparser
import pendulum
import snaptime
from tzlocal import get_localzone
from dateutil.relativedelta import relativedelta
from .compat import cmp, comparable
@@ -423,6 +425,29 @@ class MayaInterval(object):
"""Returns an ISO 8601 representation of the MayaInterval."""
return '{0}/{1}'.format(self.start.iso8601(), self.end.iso8601())
@classmethod
def parse_iso8601_duration(cls, duration, start=None, end=None):
match = re.match(
r'(?:P(?P<weeks>\d+)W)|(?:P(?:(?:(?P<years>\d+)Y)?(?:(?P<months>\d+)M)?(?:(?P<days>\d+)D))?(?:T(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?)?)',
duration
)
time_components = {}
if match:
time_components = match.groupdict(0)
for key, value in time_components.items():
time_components[key] = int(value)
duration = relativedelta(**time_components)
if start:
return parse(start.datetime() + duration)
if end:
return parse(end.datetime() - duration)
return None
@classmethod
def from_iso8601(cls, s):
# # Start and end, such as "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"
@@ -430,14 +455,13 @@ class MayaInterval(object):
try:
start = parse(start)
except pendulum.parsing.exceptions.ParserError:
# start = self._parse_iso8601_duration(start)
# start = self._parse_iso8601_duration(start, end=end)
raise NotImplementedError()
try:
end = parse(end)
except pendulum.parsing.exceptions.ParserError as e:
# end = self._parse_iso8601_duration(end)
raise NotImplementedError()
end = cls.parse_iso8601_duration(end, start=start)
return cls(start=start, end=end)
+20
View File
@@ -550,3 +550,23 @@ def test_interval_from_iso8601():
assert interval.start == s
assert interval.end == e
def test_interval_from_iso8601_duration():
interval = maya.MayaInterval.from_iso8601(
"2018-03-18T14:27:18Z/P13DT13H48M9S"
)
s = maya.when("2018-03-18T14:27:18Z")
e = maya.when("2018-04-01T04:15:27Z")
assert interval.start == s
assert interval.end == e
interval = maya.MayaInterval.from_iso8601(
"2018-03-05T14:27:18Z/P2W"
)
s = maya.when("2018-03-05T14:27:18Z")
e = maya.when("2018-03-19T14:27:18Z")
assert interval.start == s
assert interval.end == e