From 4fd6d1d7e01f2a7e5dcb874fbc8a81cf3906e492 Mon Sep 17 00:00:00 2001 From: benfitzpatrick Date: Wed, 26 Feb 2014 17:06:59 +0000 Subject: [PATCH] #2: support 2nd recurrence format e.g. R/P2Y. --- isodatetime/parsers.py | 28 ++++++++++++++++++++++++++-- isodatetime/tests.py | 12 +++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/isodatetime/parsers.py b/isodatetime/parsers.py index deb4fe7..314e75f 100644 --- a/isodatetime/parsers.py +++ b/isodatetime/parsers.py @@ -67,8 +67,28 @@ def __init__(self, timepoint_parser=None, timeinterval_parser=None): else: self.timepoint_parser = timeinterval_parser - def parse(self, expression): - """Parse a recurrence string into a TimeRecurrence instance.""" + def parse(self, expression, context_point=None): + """Parse a recurrence string into a TimeRecurrence instance. + + expression should be a string that looks like one of the four + ISO 8601 recurrence formats - e.g. + "R5/20140228T0630Z/20140228T0830Z" + "R5/PT10M" (with a supplied context) + "R5/20140228T0630Z/PT10M" + "R5/PT10M/20140228T0830Z" + + where the slash is a delimiter, the number following the R is + an optional limit for the number of recurrences, strings + beginning with "2014" are ISO 8601 date/time representations, + and string beginning with "P" are ISO 8601 duration + representations. + + context_point should be given for the second format, which will + then behave in the same way as the third format - start at + the context point and apply the interval counting forwards in + time. + + """ for regex in self.RECURRENCE_REGEXES: result = regex.search(expression) if not result: @@ -87,6 +107,10 @@ def parse(self, expression): if "intv" in result_map: interval = self.timeinterval_parser.parse( result_map["intv"]) + if (context_point is not None and start_point is None and + end_point is None): + # Second ISO 8601 recurrence format. + start_point = context_point return data.TimeRecurrence( repetitions=repetitions, start_point=start_point, diff --git a/isodatetime/tests.py b/isodatetime/tests.py index 3e4414f..e068fc8 100644 --- a/isodatetime/tests.py +++ b/isodatetime/tests.py @@ -444,6 +444,12 @@ def get_timerecurrenceparser_tests(): yield expr_1, {"repetitions": reps, "start_point": start_point, "end_point": end_point} + expr_2 = ("R" + reps_string + "/" + str(interval)) + yield (expr_2, start_point), { + "repetitions": reps, + "start_point": start_point, + "interval": interval + } expr_3 = ("R" + reps_string + "/" + str(start_point) + "/" + str(interval)) yield expr_3, {"repetitions": reps, @@ -588,8 +594,12 @@ def test_timerecurrence_parser(self): """Test the recurring date/time series parsing.""" parser = parsers.TimeRecurrenceParser() for expression, test_info in get_timerecurrenceparser_tests(): + context_point=None + if isinstance(expression, tuple): + expression, context_point = expression try: - test_data = str(parser.parse(expression)) + test_data = str(parser.parse(expression, + context_point=context_point)) except parsers.TimeSyntaxError: raise ValueError("Parsing failed for %s" % expression) ctrl_data = str(data.TimeRecurrence(**test_info))