验证日期范围 Args: date_range: 日期范围,支持多种格式: - dict: {"start": "YYYY-MM-DD", "end": "YYYY-MM-DD"} - JSON 字符串: '{"start": "2025-01-01", "end": "2025-01-07"}' - 单日字符串: "2025-01-01"(自动转为同一天的范围) - 自然语言: "今天", "昨天", "本周", "最近7天" 等 Returns:
(date_range: Optional[Union[dict, str]])
| 361 | |
| 362 | |
| 363 | def validate_date_range(date_range: Optional[Union[dict, str]]) -> Optional[tuple]: |
| 364 | """ |
| 365 | 验证日期范围 |
| 366 | |
| 367 | Args: |
| 368 | date_range: 日期范围,支持多种格式: |
| 369 | - dict: {"start": "YYYY-MM-DD", "end": "YYYY-MM-DD"} |
| 370 | - JSON 字符串: '{"start": "2025-01-01", "end": "2025-01-07"}' |
| 371 | - 单日字符串: "2025-01-01"(自动转为同一天的范围) |
| 372 | - 自然语言: "今天", "昨天", "本周", "最近7天" 等 |
| 373 | |
| 374 | Returns: |
| 375 | (start_date, end_date) 元组,或 None |
| 376 | |
| 377 | Raises: |
| 378 | InvalidParameterError: 日期范围无效 |
| 379 | """ |
| 380 | if date_range is None: |
| 381 | return None |
| 382 | |
| 383 | # 支持字符串形式的输入 |
| 384 | if isinstance(date_range, str): |
| 385 | stripped = date_range.strip() |
| 386 | |
| 387 | # 1. 检查是否是 JSON 对象格式 |
| 388 | if stripped.startswith('{') and stripped.endswith('}'): |
| 389 | try: |
| 390 | date_range = json.loads(stripped) |
| 391 | except json.JSONDecodeError as e: |
| 392 | raise InvalidParameterError( |
| 393 | f"date_range JSON 解析失败: {e}", |
| 394 | suggestion='请使用正确的JSON格式: {"start": "YYYY-MM-DD", "end": "YYYY-MM-DD"}' |
| 395 | ) |
| 396 | # 2. 检查是否是单日字符串格式 YYYY-MM-DD |
| 397 | elif len(stripped) == 10 and stripped[4] == '-' and stripped[7] == '-': |
| 398 | try: |
| 399 | single_date = datetime.strptime(stripped, "%Y-%m-%d") |
| 400 | return (single_date, single_date) |
| 401 | except ValueError: |
| 402 | raise InvalidParameterError( |
| 403 | f"日期格式错误: {stripped}", |
| 404 | suggestion="请使用 YYYY-MM-DD 格式,例如: 2025-10-11" |
| 405 | ) |
| 406 | # 3. 尝试自然语言解析 |
| 407 | else: |
| 408 | try: |
| 409 | result = DateParser.resolve_date_range_expression(stripped) |
| 410 | if result.get("success"): |
| 411 | dr = result["date_range"] |
| 412 | start_date = datetime.strptime(dr["start"], "%Y-%m-%d") |
| 413 | end_date = datetime.strptime(dr["end"], "%Y-%m-%d") |
| 414 | return (start_date, end_date) |
| 415 | else: |
| 416 | raise InvalidParameterError( |
| 417 | f"无法识别的日期表达式: {stripped}", |
| 418 | suggestion="支持格式: YYYY-MM-DD, {\"start\": \"...\", \"end\": \"...\"}, 或自然语言(今天、本周、最近7天等)" |
| 419 | ) |
| 420 | except InvalidParameterError: |
no test coverage detected