Source code for src.dackar.RCA.signal_evidence._util

"""Shared helpers for the signal-evidence package.

Centralizes the small utilities that were previously duplicated between
``builder.py`` and ``historian_adapter.py`` (MR#49 review), so the
UTC-normalization rule below lives in exactly one place.
"""

from __future__ import annotations

from datetime import datetime, timezone
from typing import Optional


[docs] def parse_dt(value: Optional[str]) -> Optional[datetime]: """Parse an ISO-8601 timestamp, normalized to a UTC-aware ``datetime``. A naive input (no offset, e.g. ``"2024-01-01T00:00:00"``) is assumed to be UTC and stamped with ``timezone.utc``, while offset-aware inputs (``...+00:00`` / ``...Z``) are preserved. This guarantees every downstream comparison and subtraction operates on offset-aware datetimes, avoiding ``TypeError: can't compare offset-naive and offset-aware datetimes``. Args: value: An ISO-8601 timestamp string, or ``None``/empty. Returns: A UTC-aware ``datetime``, or ``None`` when *value* is empty or cannot be parsed. """ if not value: return None try: dt = datetime.fromisoformat(str(value).replace("Z", "+00:00")) except Exception: return None if dt.tzinfo is None: dt = dt.replace(tzinfo=timezone.utc) return dt
[docs] def clamp01(x: float) -> float: """Clamp *x* to the closed unit interval ``[0.0, 1.0]``.""" return max(0.0, min(1.0, float(x)))