From 8f975c40d835db3a313ca1f898cf27dc13f9ac7e Mon Sep 17 00:00:00 2001 From: Mark Dawson Date: Tue, 19 Dec 2023 10:57:16 +0000 Subject: [PATCH] Add chained offset logic for FCP (#5885) --- changes.d/5885.fix.md | 1 + cylc/flow/cycling/iso8601.py | 15 ++++++++++++--- tests/unit/test_config.py | 17 ++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 changes.d/5885.fix.md diff --git a/changes.d/5885.fix.md b/changes.d/5885.fix.md new file mode 100644 index 00000000000..b9071bae612 --- /dev/null +++ b/changes.d/5885.fix.md @@ -0,0 +1 @@ +Fixed bug in using a final cycle point with chained offsets e.g. 'final cycle point = +PT6H+PT1S'. \ No newline at end of file diff --git a/cylc/flow/cycling/iso8601.py b/cylc/flow/cycling/iso8601.py index ed5b4f21979..3c8bd3955fa 100644 --- a/cylc/flow/cycling/iso8601.py +++ b/cylc/flow/cycling/iso8601.py @@ -895,14 +895,23 @@ def get_dump_format(): def get_point_relative(offset_string, base_point): """Create a point from offset_string applied to base_point.""" try: - interval = ISO8601Interval(str(interval_parse(offset_string))) + operator = '+' + base_point_relative = base_point + for part in re.split(r'(\+|-)', offset_string): + if part == '+' or part == '-': + operator = part + elif part != '': + interval = interval_parse(part) + if operator == '-': + interval *= -1 + base_point_relative += ISO8601Interval(str(interval)) + return base_point_relative except IsodatetimeError: + # It's a truncated time point rather than an interval return ISO8601Point(str( WorkflowSpecifics.abbrev_util.parse_timepoint( offset_string, context_point=point_parse(base_point.value)) )) - else: - return base_point + interval def interval_parse(interval_string): diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 736bd34ed9d..b3936f7c328 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -532,6 +532,17 @@ def test_process_startcp( None, id="Relative fcp" ), + pytest.param( + ISO8601_CYCLING_TYPE, + { + 'initial cycle point': '2017-02-11', + 'final cycle point': '+P4D+PT3H-PT2H', + }, + None, + '20170215T0100+0530', + None, + id="Relative fcp chained" + ), pytest.param( ISO8601_CYCLING_TYPE, { @@ -1429,11 +1440,7 @@ def test_zero_interval( ('1988-02-29', '+P1M+P1Y', '1989-03-29'), ('1910-08-14', '+P2D-PT6H', '1910-08-15T18:00'), ('1850-04-10', '+P1M-P1D+PT1H', '1850-05-09T01:00'), - pytest.param( - '1066-10-14', '+PT1H+PT1M', '1066-10-14T01:01', - marks=pytest.mark.xfail - # https://github.com/cylc/cylc-flow/issues/5047 - ), + ('1066-10-14', '+PT1H+PT1M', '1066-10-14T01:01'), ] ) def test_chain_expr(