All checks were successful
CI / lint-and-test (push) Successful in 21s
- Introduced a new `normalize_lang` function to standardize language codes across the application, ensuring consistent handling of user language preferences. - Refactored date handling utilities by adding `parse_utc_iso` and `parse_utc_iso_naive` functions for better parsing of ISO 8601 date strings, enhancing timezone awareness. - Updated various modules to utilize the new language normalization and date parsing functions, improving code clarity and maintainability. - Enhanced error handling in date validation to raise specific `DateRangeValidationError` exceptions, providing clearer feedback on validation issues. - Improved test coverage for date range validation and language normalization functionalities, ensuring robustness and reliability.
33 lines
1011 B
Python
33 lines
1011 B
Python
"""Handover time parsing for duty schedule import."""
|
|
|
|
import re
|
|
from datetime import datetime, timezone
|
|
|
|
# HH:MM or HH:MM:SS, optional space + timezone (IANA or "UTC")
|
|
HANDOVER_TIME_RE = re.compile(
|
|
r"^\s*(\d{1,2}):(\d{2})(?::(\d{2}))?\s*(?:\s+(\S+))?\s*$", re.IGNORECASE
|
|
)
|
|
|
|
|
|
def parse_handover_time(text: str) -> tuple[int, int] | None:
|
|
"""Parse handover time string to (hour_utc, minute_utc). Returns None on failure."""
|
|
m = HANDOVER_TIME_RE.match(text)
|
|
if not m:
|
|
return None
|
|
hour = int(m.group(1))
|
|
minute = int(m.group(2))
|
|
# second = m.group(3) ignored
|
|
tz_str = (m.group(4) or "").strip()
|
|
if not tz_str or tz_str.upper() == "UTC":
|
|
return (hour % 24, minute)
|
|
from zoneinfo import ZoneInfo
|
|
|
|
try:
|
|
tz = ZoneInfo(tz_str)
|
|
except Exception:
|
|
return None
|
|
# Build datetime in that tz and convert to UTC
|
|
dt = datetime(2000, 1, 1, hour, minute, 0, tzinfo=tz)
|
|
utc = dt.astimezone(timezone.utc)
|
|
return (utc.hour, utc.minute)
|