23 de agosto de 2024 • 4 min de lectura
Especialista en IA y Automatización
Diseño sistemas de comunicación impulsados por IA. Mi trabajo se centra en agentes de voz, chatbots de WhatsApp, asistentes de IA y automatización de flujos, construidos principalmente sobre Twilio, n8n y LLM modernos como OpenAI y Claude. En los últimos 7 años he entregado más de 30 proyectos de automatización que manejan más de 250 000 interacciones mensuales.
Si te gusta el contenido que hago, puedes suscribirte y recibir información valiosa por correo. No se envía spam, solo novedades sobre publicaciones interesantes o contenido especializado del que hablo.
Laravel hace fácil el manejo de fechas, pero elegir mal el tipo de columna o la estrategia de timezone te trae problemas de integridad de datos más adelante. Mucha gente busca la diferencia entre DateTime y Timestamp en Laravel, y la clave real está en cómo guardás y cómo mostrás ese dato. En esta guía comparo los dos tipos, explico la limitación del "año 2038" y vemos las conversiones a UTC.
Cuando escribís migraciones elegís entre $table->timestamp() y $table->dateTime(). Este es el desglose técnico
| Característica | Timestamp | DateTime |
|---|---|---|
| Rango en MySQL | 1970-01-01 to 2038-01-19 | 0001-01-01 to 9999-12-31 |
| Tamaño | 4 bytes | 8 bytes |
| Manejo de TZ | Convierte a UTC al guardar | Guarda el valor literal (ignora el offset) |
| Default de Laravel | Lo usa $table->timestamps() | Hay que definirlo a mano |
Una diferencia crítica es que los Timestamps se guardan como un entero de 32 bits que representa los segundos desde el Unix Epoch. O sea que van a desbordar el 19 de enero de 2038. Si tu aplicación maneja fechas lejanas, como hipotecas a 30 años o fechas de nacimiento, usá columnas DateTime para esquivar ese límite.
Se cree que Laravel siempre guarda los timestamps en UTC, y no es así. Laravel guarda con la timezone que hayas puesto en config/app.php. Si tu app está en America/New_York, entonces created_at se guarda en hora del Este.
Buena práctica: poné siempre la timezone de la aplicación en UTC. Guardar en UTC te evita los saltos de horario de verano y te ordena las integraciones con servicios como Stripe, Twilio y AWS.
Laravel no asume que tu base está en UTC. Lee el valor crudo y lo envuelve en una instancia de Carbon, usando la timezone que definiste en el config.
// config/app.php
'timezone' => 'UTC';
$post = Post::find(1);
// Even if stored as a 'datetime' column, Carbon treats it as UTC
echo $post->created_at->timezone; // "UTC"
Mientras el config sea consistente, Carbon hace las conversiones claras y predecibles en todo el codebase.
Guardar los timestamps en UTC encaja perfecto con el ecosistema de Laravel y con los paquetes de terceros:
Una vez que el dato está guardado en UTC, tenés que mostrárselo al usuario en su hora local.
Lo más simple es mandar el string UTC en ISO-8601 al frontend y dejar que JavaScript, o el frontend que uses, se encargue del resto.
// The 'Z' denotes UTC
let utcTimestamp = "2024-08-23T12:00:00Z";
let localDate = new Date(utcTimestamp);
console.log(localDate.toLocaleString());
Si guardás la timezone preferida del usuario en la tabla users, podés convertirla antes de que el dato llegue a la vista.
$userTimezone = auth()->user()->timezone; // e.g., 'Europe/Madrid'
$converted = $post->created_at->setTimezone($userTimezone);
Un aspecto complicado de las timezones es el DST. Por suerte, Carbon y los objetos Date modernos de JavaScript lo manejan solos. Eso sí: usá strings basados en ubicación (como America/New_York) en lugar de offsets fijos (como -05:00).
La discusión DateTime vs Timestamp en Laravel suele terminar en el rango de almacenamiento, pero lo que de verdad importa es aplicar un workflow estricto: guardar en UTC, mostrar en local. Resolverlo ahora te ahorra dolores de cabeza enormes cuando la aplicación crezca a otros países.
¡A codear!
Descubre cuánto te está costando tu sistema de comunicaciones.
Obtén la auditoría de comunicaciones