Manual de campo · trampas de SQL
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.
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.
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 →