English

Manual de campo · trampas de SQL

Zonas horarias: guarda UTC, muestra local

Agrupar por día sin decidir el huso horario reparte la misma sesión entre dos días, y el cambio de hora crea un día de 23 horas y otro de 25.

Cuándo aparece

Cualquier dato con marca de tiempo que cruce husos horarios o un cambio de hora — casi todos los sistemas con usuarios en más de una zona.

Ejemplo

Mal: date_trunc sin decidir el huso

SELECT date_trunc('day', momento_utc) AS dia
FROM sesiones
GROUP BY dia;
-- momento_utc no lleva huso: date_trunc corta en el día UTC.
-- En Ciudad de México (UTC−6) todo lo que pasa después de las
-- 18:00 se apunta al día siguiente

Bien: las dos conversiones, en ese orden

SELECT date_trunc(
  'day',
  momento_utc AT TIME ZONE 'UTC' AT TIME ZONE 'America/Mexico_City'
) AS dia_local
FROM sesiones
GROUP BY dia_local;

Hacen falta las dos conversiones y en ese orden: la primera dice qué instante representa ese TIMESTAMP guardado sin huso (interpretarlo como UTC), la segunda lo traduce al reloj de allí. Con una sola conversión, el motor devuelve un instante y el date_trunc corta usando el huso de la máquina — el mismo dato da un día distinto en cada ordenador, y un cambio de hora reparte la misma sesión de la noche entre dos fechas.

Esta trampa —y otras cuatro más— están escondidas en un caso de verdad, con datos de verdad.

Jugar el caso 1 gratis →

Otras trampas