Timestamps Epoch Explicados: Cómo Funciona el Tiempo Unix (y Por Qué Falla)
Un timestamp epoch — también llamado tiempo Unix o tiempo POSIX — es el número de segundos que han transcurrido desde el 1 de enero de 1970 a las 00:00:00 UTC, excluyendo segundos intercalares. Es un entero simple que representa un momento preciso en el tiempo, independiente de las zonas horarias y los sistemas de calendario. Esta simplicidad lo convierte en la forma estándar en que las computadoras intercambian información de tiempo, pero también tiene limitaciones y problemas conocidos que todo desarrollador debería entender.
Cómo Funciona el Tiempo Unix
El tiempo Unix cuenta hacia adelante desde la época. Un día equivale a 86,400 segundos (24 × 60 × 60). El timestamp aumenta exactamente en uno por segundo, sin importar la zona horaria, el horario de verano o los años bisiestos.
Timestamp 0 → 1970-01-01 00:00:00 UTC
Timestamp 86400 → 1970-01-02 00:00:00 UTC
Timestamp 1000000 → 1970-01-12 13:46:40 UTC
Timestamp 1782000000 → 2026-06-17 00:00:00 UTC
// JavaScript — obtener timestamp Unix actual
const nowInSeconds = Math.floor(Date.now() / 1000);
console.log(nowInSeconds);
// Convertir timestamp a fecha
const date = new Date(nowInSeconds * 1000);
console.log(date.toISOString());
// PHP — obtener timestamp Unix actual
echo time(); // segundos desde epoch
echo microtime(true); // segundos con precisión de microsegundos
// Convertir timestamp a fecha
echo date('Y-m-d H:i:s', 1782000000);
Segundos vs Milisegundos: Una Fuente Común de Errores
Uno de los errores más frecuentes relacionados con timestamps es confundir segundos con milisegundos. El Date.now() de JavaScript devuelve milisegundos, mientras que time() de PHP devuelve segundos. Muchas bases de datos almacenan timestamps en segundos, y muchas APIs usan milisegundos.
| Sistema | Unidad | Ejemplo de Valor | Fecha |
|---|---|---|---|
| Unix / POSIX | Segundos | 1782000000 |
2026-06-17 |
JavaScript Date.now() |
Milisegundos | 1782000000000 |
2026-06-17 |
Java System.currentTimeMillis() |
Milisegundos | 1782000000000 |
2026-06-17 |
PHP time() |
Segundos | 1782000000 |
2026-06-17 |
Python time.time() |
Segundos (float) | 1782000000.123 |
2026-06-17 |
// ❌ Incorrecto — tratar milisegundos como segundos
const timestamp = 1782000000; // esto está en segundos
const wrongDate = new Date(timestamp); // interpreta como milisegundos
console.log(wrongDate.toISOString()); // 1970-01-21 — completamente incorrecto
// ✅ Correcto — multiplicar por 1000
const correctDate = new Date(timestamp * 1000);
console.log(correctDate.toISOString()); // 2026-06-17
import time
from datetime import datetime
# ❌ Incorrecto — olvidar dividir milisegundos
millis = 1782000000000
wrong = datetime.fromtimestamp(millis) # ValueError: year out of range
# ✅ Correcto
correct = datetime.fromtimestamp(millis / 1000)
print(correct) # 2026-06-17 00:00:00
El Problema del Año 2038
El tiempo Unix usa un entero con signo de 32 bits, cuyo valor máximo es 2,147,483,647. El 19 de enero de 2038 a las 03:14:07 UTC, el timestamp alcanzará este límite. Un segundo después, un entero con signo de 32 bits se vuelve −2,147,483,648, que corresponde al 13 de diciembre de 1901.
2,147,483,647 → 2038-01-19 03:14:07 UTC (máximo 32-bit con signo)
2,147,483,648 → se vuelve negativo (desbordamiento)
Sistemas aún vulnerables a Y2038:
- Sistemas embebidos (routers, dispositivos IoT, firmware de automóviles)
- Bases de datos heredadas que almacenan timestamps como
INT(10) - Kernels antiguos de Linux en arquitecturas de 32 bits
- Sistemas de archivos que usan timestamps de 32 bits
- Versiones antiguas de PHP en compilaciones de 32 bits
Cómo verificar si un sistema es seguro para Y2038:
# Linux — verificar si time_t es de 64 bits
getconf LONG_BIT
# 64 → seguro
# 32 → verificar kernel y versión de libc
# PHP — verificar tamaño de entero
php -r 'echo PHP_INT_SIZE;'
# 8 → seguro (64 bits)
# 4 → vulnerable (32 bits)
Los sistemas modernos con time_t de 64 bits pueden representar timestamps hasta aproximadamente 292 mil millones de años en el futuro, haciendo de Y2038 un problema inexistente. La mayoría de los servidores de producción ya ejecutan sistemas operativos de 64 bits, pero los sistemas embebidos y heredados siguen en riesgo.
Segundos Intercalares: La Complejidad Oculta
El tiempo Unix ignora los segundos intercalares. Por definición, cada día tiene exactamente 86,400 segundos. Pero el tiempo astronómico (UT1) ocasionalmente requiere un segundo adicional — un segundo intercalar — para mantenerse alineado con la rotación terrestre. Cuando ocurre un segundo intercalar, el tiempo Unix repite el mismo segundo:
2016-12-31 23:59:59 UTC
2016-12-31 23:59:60 UTC ← segundo intercalar (no representable en tiempo Unix)
2017-01-01 00:00:00 UTC
La mayoría de las aplicaciones ignoran los segundos intercalares por completo porque ocurren de manera impredecible (generalmente cada 1-3 años) y manejarlos añade una complejidad significativa. Los sistemas que requieren una medición precisa del tiempo — como plataformas de trading financiero y observatorios astronómicos — usan TAI (Tiempo Atómico Internacional) o tiempo GPS en lugar del tiempo Unix.
Errores Comunes
Error 1: Usar la Unidad Incorrecta
// La API devuelve timestamp en segundos
const apiTimestamp = 1782000000;
// ❌ Incorrecto — new Date() espera milisegundos
const date = new Date(apiTimestamp);
// ✅ Correcto
const date = new Date(apiTimestamp * 1000);
Error 2: Almacenar como INT(10) en MySQL
-- ❌ Incorrecto — INT(10) se desborda en 2.1 mil millones (2038)
CREATE TABLE events (
created_at INT(10) NOT NULL
);
-- ✅ Correcto — usar BIGINT o TIMESTAMP
CREATE TABLE events (
created_at BIGINT NOT NULL, -- 64 bits, seguro
created_at2 TIMESTAMP NOT NULL -- MySQL maneja la conversión
);
Error 3: Asumir que la Hora Local es la Predeterminada
// ❌ Incorrecto — date() usa la zona horaria predeterminada del servidor
echo date('Y-m-d H:i:s', $timestamp);
// ✅ Correcto — especificar explícitamente UTC
echo gmdate('Y-m-d H:i:s', $timestamp);
echo date('Y-m-d H:i:s', $timestamp); // si la zona predeterminada está en UTC
Error 4: Desbordamiento de Enteros en JavaScript
Los números en JavaScript son punto flotante de 64 bits, pero las operaciones bit a bit los tratan como enteros con signo de 32 bits. Esto puede causar errores inesperados similares a Y2038 incluso en navegadores modernos.
// La operación bit a bit en JavaScript trata como 32 bits
const timestamp = 2500000000; // más allá del máximo de 32 bits con signo
const shifted = timestamp << 1; // ❌ desbordamiento
console.log(shifted); // -1794967296 (envuelto)
Herramienta de Conversión de Epoch
La herramienta Convertidor de Timestamp Epoch / Unix en Help2Code proporciona visualización en vivo del timestamp actual en segundos y milisegundos, conversión bidireccional entre valores epoch y fechas legibles, y soporte para zonas horarias locales y UTC. Úsala para depurar problemas de timestamps, generar timestamps para pruebas o verificar respuestas de API. La herramienta Convertidor de Zona Horaria también es útil para verificar cómo los timestamps epoch se corresponden con diferentes zonas horarias.
Conclusión
Los timestamps epoch son una forma simple y universal de representar momentos en el tiempo, pero vienen con algunas advertencias críticas: verifica siempre si estás trabajando con segundos o milisegundos, usa almacenamiento de 64 bits para evitar el problema Y2038, y nunca asumas que la zona horaria predeterminada coincide con tu intención. Usa la herramienta Convertidor de Epoch para conversiones rápidas y ten en cuenta las pautas anteriores al manejar timestamps en código de producción.