from __future__ import annotations from datetime import datetime, timezone from pathlib import Path import os from typing import Optional DEFAULT_PATH = Path("last_execution.txt") DEFAULT_FALLBACK = datetime(2024, 1, 1, 0, 0, 0, tzinfo=timezone.utc) FMT = "%Y-%m-%d %H:%M:%S" def obtener_fecha_ultima_ejecucion( path: str = DEFAULT_PATH, *, fallback: Optional[datetime] = None, ) -> datetime: """ Lee la última fecha de ejecución desde `path` y la devuelve como aware (UTC). - Si el fichero no existe o el contenido es inválido, devuelve `fallback`. - Si `fallback` es None, usa DEFAULT_FALLBACK (2024-01-01T00:00:00Z). """ # Comentario: fallback explícito para evitar lógica duplicada en llamadas effective_fallback = fallback or DEFAULT_FALLBACK if path is None: return effective_fallback # 2. Convertimos str -> Path path = Path(path) try: text = path.read_text(encoding="utf-8").strip() if not text: # Comentario: fichero vacío -> usamos fallback return effective_fallback dt_naive = datetime.strptime(text, FMT) return dt_naive.replace(tzinfo=timezone.utc) except FileNotFoundError: return effective_fallback except ValueError: # Comentario: formato inválido en el archivo -> fallback return effective_fallback def actualizar_fecha_ultima_ejecucion( path: str = DEFAULT_PATH, *, momento: Optional[datetime] = None, ) -> None: """ Escribe en `path` la fecha/hora (UTC) en formato YYYY-MM-DD HH:MM:SS. Si `momento` es None, usa ahora en UTC. Crea directorios intermedios si no existen. """ if momento is None: momento = datetime.now(timezone.utc) else: # Normalizamos a UTC si viene con tz; si es naive, asumimos UTC if momento.tzinfo is None: momento = momento.replace(tzinfo=timezone.utc) else: momento = momento.astimezone(timezone.utc) # Asegurar carpeta si `path` incluye directorios folder = os.path.dirname(os.path.abspath(path)) if folder and not os.path.exists(folder): os.makedirs(folder, exist_ok=True) with open(path, "w", encoding="utf8") as f: f.write(momento.strftime(FMT))