# Time Utils

Fuente conceptual: OpenViking `openviking/utils/time_utils.py` (AGPL-3.0)
Reimplementar desde cero. No copiar codigo.

## Funciones a implementar

### 1. parse_iso_datetime

- **Dominio:** core
- **Lang:** Python
- **Purity:** pure
- **Signature:** `parse_iso_datetime(value: str) -> datetime`
- **Descripcion:** Parsea un datetime ISO 8601 tolerando >6 digitos en fracciones de segundo (Windows produce timestamps como `2026-02-21T13:20:23.1470042+08:00` donde los microsegundos exceden 6 digitos de Python).
- **Algoritmo:**
  1. Regex: truncar fracciones de segundo a 6 digitos: `(\.\d{6})\d+` → `\1`
  2. Reemplazar `Z` final por `+00:00`
  3. `datetime.fromisoformat(normalized)`
- **Deps:** `re`, `datetime`
- **Tests:** ISO normal, ISO con Z, ISO con >6 digitos fraccion, ISO con timezone offset

### 2. format_iso8601

- **Dominio:** core
- **Lang:** Python
- **Purity:** pure
- **Signature:** `format_iso8601(dt: datetime) -> str`
- **Descripcion:** Formatea datetime a ISO 8601 UTC con milisegundos. Formato: `yyyy-MM-ddTHH:mm:ss.SSSZ`
- **Algoritmo:**
  1. Si naive (sin tzinfo): asumir UTC
  2. Si aware: convertir a UTC con `astimezone(timezone.utc)`
  3. `dt.isoformat(timespec="milliseconds").replace("+00:00", "Z")`
- **Deps:** `datetime`
- **Tests:** datetime naive, datetime con timezone, datetime UTC

### 3. format_simplified

- **Dominio:** core
- **Lang:** Python
- **Purity:** pure
- **Signature:** `format_simplified(dt: datetime, now: datetime) -> str`
- **Descripcion:** Formato humano simplificado: si es del mismo dia muestra `HH:MM:SS`, si no muestra `YYYY-MM-DD`.
- **Algoritmo:**
  1. Remover tzinfo para comparacion simple
  2. Si `(now - dt).days < 1`: retornar `dt.strftime("%H:%M:%S")`
  3. Si no: retornar `dt.strftime("%Y-%m-%d")`
- **Deps:** `datetime`
- **Tests:** mismo dia (formato hora), dia anterior (formato fecha), exactamente 24h
