Datos, calidad y series · Última actualización: 2026-01-27

Timestamps: UTC, zonas horarias y desfases: checklist práctico

Vale, aquí va nuestro checklist práctico para timestamps: el que sacamos cuando algo “huele raro” y queremos dejarlo fino sin entrar en bucles 😄. La idea es que puedas pasar de “algo no cuadra” a “ya está controlado” en 10–30 minutos, según el desastre.

Tema: Calidad de datos · Enfoque: checklist operativo.

1. Objetivo y regla de oro

Objetivo: que tu serie temporal sea coherente, comparable y verificable.

Regla de oro: almacenar en UTC (canónico) y convertir a hora local solo para mostrar usando zona IANA (p.ej. Europe/Madrid).

2. Checklist express (lo mínimo que siempre miramos)

  1. ¿El dato está en UTC real? (ISO8601 con “Z” o +00:00)
  2. ¿La UI convierte a local solo una vez? (evitar doble offset)
  3. ¿Hay gaps? (cortes de alimentación/red/logger)
  4. ¿Hay duplicados? (redondeos + reintentos)
  5. ¿Hay out-of-order? (datos llegando tarde)
  6. ¿Agregación definida? (timestamp= inicio/fin/centro)
  7. ¿Corte diario definido? (día local vs día UTC)
  8. ¿Hay metadatos de cambios? (firmware/logger, NTP, mantenimiento)

3. Pruebas rápidas (sin herramientas raras)

3.1 Prueba “offset fijo” (1h/2h)

Compara un evento claro (amanecer/radiación máxima, cambio brusco de viento, lluvia con radar si hay). Si todo está corrido exactamente 3600s o 7200s durante semanas, casi seguro es doble conversión o tz mal asumida.

3.2 Prueba “cambio de hora”

Revisa el día del salto DST: si aparece un hueco o una hora repetida en almacenamiento, es que guardas local o mezclas naive timestamps.

3.3 Prueba “gap → backfill” (especial lluvia)

Si hay un gap de 20–60 min y luego aparece un pico enorme de precipitación, sospecha backfill (datos acumulados enviados con hora de llegada).

3.4 Prueba “monotonía”

El tiempo debería crecer. Si ves saltos atrás, hay out-of-order o mezcla de observed_time/ingest_time.

3.5 Prueba “agregado coherente”

Si agregas cada 10 min, confirma qué significa el timestamp. Si tu lluvia 10-min parece adelantada/atrasada respecto al radar, puede ser “timestamp al final” vs “al inicio”.

4. Checklist completo (paso a paso, con acciones)

4.1 Entrada (logger → API)

  • ¿El logger manda UTC o local? (documentar)
  • ¿El payload incluye zona o “Z”? (si no, peligro)
  • ¿Hay NTP activo o RTC fiable? (si no, drift)
  • ¿Hay reintentos? ¿hay redondeo a minuto? (duplicados)

4.2 Ingesta (API → cola → DB)

  • ¿Se guarda observed_time real?
  • ¿Se guarda ingest_time para diagnóstico?
  • ¿Se acepta out-of-order? (si sí, ¿se reordena o versiona backfill?)
  • ¿Hay validación de schema/timezone?

4.3 Almacenamiento (DB/archivos)

  • UTC canónico consistente
  • Índices por timestamp
  • Reglas anti-duplicados (idempotencia)
  • Flags QC asociados a puntos/ventanas

4.4 Transformación y agregación

  • Convención timestamp del agregado: start/end/center
  • Definir ventana (rolling vs bins fijos)
  • Tratamiento de gaps: marcar ventana como incompleta
  • Definir dayDefinition (local vs UTC) para diarios

4.5 Presentación (panel/UI)

  • Conversión a local usando zona IANA
  • Evitar doble conversión
  • Mostrar “hora del dato” y si aplica “hora de emisión” (si son productos)
  • Mostrar avisos QC si hay gaps/backfill

5. Tabla rápida: síntoma → causa probable → qué hacer (5 minutos)

SíntomaCausa probableAcción rápida
Todo corrido 1h/2hDoble conversión o tz mal asumidaAuditar dónde se convierte; dejar solo en UI
Falla solo en marzo/octubreStorage en local/DSTMigrar a UTC en DB; UI local
Picos de lluvia tras cortesBackfill/arrival-timeSeparar observed vs ingest; reetiquetar backfill
Duplicados al minutoRedondeo + reintentosIdempotencia por (sensor+timestamp original)
Gráfica “va hacia atrás”Out-of-orderReordenar o buffer; flag qc_time_out_of_order
Diarios no cuadranCorte local vs UTC mezcladoUnificar dayDefinition; recalcular
Max radiación/UV a horas rarasOffset/driftRevisar NTP/RTC; medir drift
Series con huecos rarosGaps por red/energíaFlag qc_time_gap + mostrar cobertura

6. Ejemplos típicos (para entrenar el ojo)

6.1 Caso A: doble conversión

El logger manda local, el servidor asume UTC y luego la UI convierte a local otra vez. Resultado: desplazamiento fijo y todo “parece” coherente… hasta que comparas con otra red.

6.2 Caso B: backfill en convectiva

Se cae el enlace 40 min. Al volver, se sube todo junto con timestamp de llegada: aparece un pico brutal. Si no miras el gap, juras que ha caído un diluvio bíblico.

6.3 Caso C: agregación mal interpretada

Tu 10-min tiene timestamp al final de la ventana, pero lo interpretas como inicio. Te sale todo “adelantado” 10 min y te peleas con el radar sin necesidad.

7. Checklist de salida (cuando damos por “fino” el tema)

  • UTC en almacenamiento verificado
  • Conversión local única y documentada
  • Agregación y dayDefinition documentadas
  • QC mínimo: gaps, duplicados, out-of-order, offset/drift
  • Convectiva: detector de backfill implementado o procedimiento claro

8. Referencias

  • Met Office
  • WMO
  • NOAA