|
13 | 13 |
|
14 | 14 | import mimetypes |
15 | 15 | import re |
16 | | -from datetime import datetime |
| 16 | +from datetime import datetime, time |
17 | 17 | from pathlib import Path |
18 | 18 | from typing import List, Optional, Annotated, Dict |
19 | 19 |
|
@@ -46,15 +46,43 @@ def to_snake_case(name: str) -> str: |
46 | 46 | return s2.lower() |
47 | 47 |
|
48 | 48 |
|
| 49 | +def parse_timeframe(timeframe: str) -> datetime: |
| 50 | + """Parse timeframe with special handling for 'today' and other natural language expressions. |
| 51 | +
|
| 52 | + Args: |
| 53 | + timeframe: Natural language timeframe like 'today', '1d', '1 week ago', etc. |
| 54 | +
|
| 55 | + Returns: |
| 56 | + datetime: The parsed datetime for the start of the timeframe |
| 57 | +
|
| 58 | + Examples: |
| 59 | + parse_timeframe('today') -> 2025-06-05 00:00:00 (start of today) |
| 60 | + parse_timeframe('1d') -> 2025-06-04 14:50:00 (24 hours ago) |
| 61 | + parse_timeframe('1 week ago') -> 2025-05-29 14:50:00 (1 week ago) |
| 62 | + """ |
| 63 | + if timeframe.lower() == "today": |
| 64 | + # Return start of today (00:00:00) |
| 65 | + return datetime.combine(datetime.now().date(), time.min) |
| 66 | + else: |
| 67 | + # Use dateparser for other formats |
| 68 | + parsed = parse(timeframe) |
| 69 | + if not parsed: |
| 70 | + raise ValueError(f"Could not parse timeframe: {timeframe}") |
| 71 | + return parsed |
| 72 | + |
| 73 | + |
49 | 74 | def validate_timeframe(timeframe: str) -> str: |
50 | 75 | """Convert human readable timeframes to a duration relative to the current time.""" |
51 | 76 | if not isinstance(timeframe, str): |
52 | 77 | raise ValueError("Timeframe must be a string") |
53 | 78 |
|
54 | | - # Parse relative time expression |
55 | | - parsed = parse(timeframe) |
56 | | - if not parsed: |
57 | | - raise ValueError(f"Could not parse timeframe: {timeframe}") |
| 79 | + # Preserve special timeframe strings that need custom handling |
| 80 | + special_timeframes = ["today"] |
| 81 | + if timeframe.lower() in special_timeframes: |
| 82 | + return timeframe.lower() |
| 83 | + |
| 84 | + # Parse relative time expression using our enhanced parser |
| 85 | + parsed = parse_timeframe(timeframe) |
58 | 86 |
|
59 | 87 | # Convert to duration |
60 | 88 | now = datetime.now() |
|
0 commit comments