diff --git a/redmine_reporter/cli.py b/redmine_reporter/cli.py index 7709150..482187e 100644 --- a/redmine_reporter/cli.py +++ b/redmine_reporter/cli.py @@ -25,20 +25,27 @@ def parse_date_range(date_arg: str) -> tuple[str, str]: from_date, to_date = parts[0].strip(), parts[1].strip() date_pattern = r"\d{4}-\d{2}-\d{2}" - if not re.fullmatch(date_pattern, from_date) or not re.fullmatch( - date_pattern, to_date + datetime_pattern = r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}" + if re.fullmatch(date_pattern, from_date) and re.fullmatch(date_pattern, to_date): + fmt = "%Y-%m-%d" + elif re.fullmatch(datetime_pattern, from_date) and re.fullmatch( + datetime_pattern, to_date ): + fmt = "%Y-%m-%dT%H:%M:%S" + else: raise ValueError("Date range must be in format YYYY-MM-DD--YYYY-MM-DD") try: - start = datetime.strptime(from_date, "%Y-%m-%d").date() - end = datetime.strptime(to_date, "%Y-%m-%d").date() + start = datetime.strptime(from_date, fmt) + end = datetime.strptime(to_date, fmt) except ValueError as e: raise ValueError("Date range contains invalid calendar date") from e if start > end: raise ValueError("Date range start must be less than or equal to end") + if fmt == "%Y-%m-%d": + return start.date().isoformat(), end.date().isoformat() return start.isoformat(), end.isoformat() diff --git a/tests/test_cli.py b/tests/test_cli.py index c1085be..b684cc2 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -30,6 +30,10 @@ def _reset_config_overrides(): [ ("2026-01-01--2026-01-31", ("2026-01-01", "2026-01-31")), (" 2026-01-01 -- 2026-01-31 ", ("2026-01-01", "2026-01-31")), + ( + "2026-06-01T00:00:00--2026-06-30T23:59:59", + ("2026-06-01T00:00:00", "2026-06-30T23:59:59"), + ), ], ) def test_parse_date_range_valid(date_arg, expected): @@ -43,6 +47,9 @@ def test_parse_date_range_valid(date_arg, expected): "2026-1-01--2026-01-31", "2026-02-30--2026-03-01", "2026-02-01--2026-01-31", + "2026-06-01T25:00:00--2026-06-30T23:59:59", + "2026-06-01--2026-06-30T23:59:59", + "2026-06-30T23:59:59--2026-06-01T00:00:00", ], ) def test_parse_date_range_invalid(date_arg): @@ -1372,11 +1379,6 @@ class TestReportNoTimeIntegration: # --------------------------------------------------------------------------- -@pytest.mark.xfail( - strict=True, - reason="bug #59: parse_date_range rejects datetime range produced by " - "dynamic period with precision=datetime when --date is omitted", -) @mock.patch.dict(os.environ, VALID_ENV, clear=True) @mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time") def test_cli_dynamic_datetime_period_without_date(mock_fetch, tmp_path):