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, y 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 está escondida en un caso de verdad, con datos de verdad.
Jugar el caso 1 gratis →