feat(cli): add natural language date parsing via dateparser
- Add _parse_natural() to utils.py using dateparser as a fallback when structured date formats (YYYY-MM-DD, MM-DD, DD-MM) don't match - Supports expressions like 'today', 'yesterday', 'monday', '3 days ago' - Change day argument to nargs='*' and join tokens so unquoted multi-word expressions like: uv run timesheets 3 days ago work correctly - Pin dateparser to English to avoid locale-dependent behaviour - Update tests to cover natural language cases and fix test_last_monday (dateparser does not support 'last monday'; use 'monday' instead)
This commit is contained in:
parent
29698b1241
commit
615bfe30e0
6 changed files with 207 additions and 13 deletions
|
|
@ -63,10 +63,29 @@ def parse_date_arg(value: str) -> date:
|
|||
raise ValueError(f"Invalid date: {value!r}")
|
||||
return result
|
||||
|
||||
raise ValueError(
|
||||
f"Unrecognised date format: {value!r}. "
|
||||
"Expected YYYY-MM-DD, MM-DD, or DD-MM (- or / as separator)."
|
||||
# Nothing matched structured formats — try natural language
|
||||
return _parse_natural(value)
|
||||
|
||||
|
||||
def _parse_natural(value: str) -> date:
|
||||
"""
|
||||
Parse a natural language date string using dateparser.
|
||||
Raises ValueError if the string cannot be interpreted.
|
||||
"""
|
||||
import dateparser
|
||||
|
||||
result = dateparser.parse(
|
||||
value,
|
||||
languages=["en"],
|
||||
settings={"PREFER_DATES_FROM": "past", "RETURN_AS_TIMEZONE_AWARE": False},
|
||||
)
|
||||
if result is None:
|
||||
raise ValueError(
|
||||
f"Could not interpret {value!r} as a date. "
|
||||
"Try a structured format like '2026-05-22' or '05-22', "
|
||||
"or a relative expression like 'today', 'yesterday', 'monday', or '3 days ago'."
|
||||
)
|
||||
return result.date()
|
||||
|
||||
|
||||
def parse_duration(duration_str: str) -> float:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue