|
4 | 4 | """Types for the CLI client.""" |
5 | 5 |
|
6 | 6 | import json |
7 | | -from datetime import datetime, timedelta, timezone |
| 7 | +from datetime import datetime, timedelta, timezone, time |
8 | 8 | from itertools import chain |
9 | 9 | from typing import Any, Literal, cast |
| 10 | +import re |
10 | 11 |
|
11 | 12 | import asyncclick as click |
12 | 13 | import parsedatetime # type: ignore |
@@ -53,7 +54,28 @@ def convert( |
53 | 54 | if value.upper() == "NOW": |
54 | 55 | return "NOW" |
55 | 56 |
|
56 | | - parsed_dt, parse_status = self.cal.parseDT(value, tzinfo=self.local_tz) |
| 57 | + # Check if this looks like a date-only string (e.g., "2025-08-06", "2025/08/06", "Aug 6, 2025") |
| 58 | + # Use midnight as the default time only for date-only strings, not relative times |
| 59 | + date_only_patterns = [ |
| 60 | + r'^\d{4}-\d{1,2}-\d{1,2}$', # YYYY-MM-DD or YYYY-M-D |
| 61 | + r'^\d{4}/\d{1,2}/\d{1,2}$', # YYYY/MM/DD or YYYY/M/D |
| 62 | + r'^\d{1,2}/\d{1,2}/\d{4}$', # MM/DD/YYYY or M/D/YYYY |
| 63 | + r'^\d{1,2}-\d{1,2}-\d{4}$', # MM-DD-YYYY or M-D-YYYY |
| 64 | + ] |
| 65 | + |
| 66 | + is_date_only = any(re.match(pattern, value.strip()) for pattern in date_only_patterns) |
| 67 | + |
| 68 | + if is_date_only: |
| 69 | + # Use midnight as the default time for date-only strings |
| 70 | + midnight_source = datetime.combine( |
| 71 | + datetime.now().date(), time(0, 0, 0), tzinfo=self.local_tz |
| 72 | + ) |
| 73 | + parsed_dt, parse_status = self.cal.parseDT( |
| 74 | + value, sourceTime=midnight_source, tzinfo=self.local_tz |
| 75 | + ) |
| 76 | + else: |
| 77 | + # Use current time for relative expressions like "in 1 hour" |
| 78 | + parsed_dt, parse_status = self.cal.parseDT(value, tzinfo=self.local_tz) |
57 | 79 | if parse_status == 0: |
58 | 80 | self.fail(f"Invalid time expression: {value}", param, ctx) |
59 | 81 |
|
|
0 commit comments