Files
duty-teller/duty_teller/utils/handover.py
Nikolay Tatarinov 28973489a5 Refactor project structure and enhance Docker configuration
- Updated `.dockerignore` to exclude test and development artifacts, optimizing the Docker image size.
- Refactored `main.py` to delegate execution to `duty_teller.run.main()`, simplifying the entry point.
- Introduced a new `duty_teller` package to encapsulate core functionality, improving modularity and organization.
- Enhanced `pyproject.toml` to define a script for running the application, streamlining the execution process.
- Updated README documentation to reflect changes in project structure and usage instructions.
- Improved Alembic environment configuration to utilize the new package structure for database migrations.
2026-02-18 13:03:14 +03:00

38 lines
1.2 KiB
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)
try:
from zoneinfo import ZoneInfo
except ImportError:
try:
from backports.zoneinfo import ZoneInfo # type: ignore
except ImportError:
return None
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)