|
3 | 3 | import re |
4 | 4 | import warnings |
5 | 5 | from datetime import datetime, timezone |
6 | | -from typing import Literal |
| 6 | +from typing import Literal, TypedDict |
7 | 7 |
|
| 8 | +from typing_extensions import NotRequired |
8 | 9 | from whenever import Date, Instant, LocalDateTime, OffsetDateTime, Time, ZonedDateTime |
9 | 10 |
|
10 | 11 | from .exceptions import TimestampFormatError |
11 | 12 |
|
12 | 13 | UTC = timezone.utc # Required for older versions of Python |
13 | 14 |
|
| 15 | + |
| 16 | +class SubstractParams(TypedDict): |
| 17 | + seconds: NotRequired[float] |
| 18 | + minutes: NotRequired[float] |
| 19 | + hours: NotRequired[float] |
| 20 | + |
| 21 | + |
14 | 22 | REGEX_MAPPING = { |
15 | 23 | "seconds": r"(\d+)(s|sec|second|seconds)", |
16 | 24 | "minutes": r"(\d+)(m|min|minute|minutes)", |
@@ -73,14 +81,19 @@ def _parse_string(cls, value: str) -> ZonedDateTime: |
73 | 81 | except ValueError: |
74 | 82 | pass |
75 | 83 |
|
76 | | - params: dict[str, float] = {} |
| 84 | + params: SubstractParams = {} |
77 | 85 | for key, regex in REGEX_MAPPING.items(): |
78 | 86 | match = re.search(regex, value) |
79 | 87 | if match: |
80 | | - params[key] = float(match.group(1)) |
| 88 | + if key == "seconds": |
| 89 | + params["seconds"] = float(match.group(1)) |
| 90 | + elif key == "minutes": |
| 91 | + params["minutes"] = float(match.group(1)) |
| 92 | + elif key == "hours": |
| 93 | + params["hours"] = float(match.group(1)) |
81 | 94 |
|
82 | 95 | if params: |
83 | | - return ZonedDateTime.now("UTC").subtract(**params) # type: ignore[call-overload] |
| 96 | + return ZonedDateTime.now("UTC").subtract(**params) |
84 | 97 |
|
85 | 98 | raise TimestampFormatError(f"Invalid time format for {value}") |
86 | 99 |
|
|
0 commit comments