mirror of
https://github.com/kennethreitz/maya.git
synced 2026-06-05 14:50:19 +00:00
Parsing an ISO8601 duration for an interval
This commit is contained in:
+27
-3
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user