FROM_UNIXTIME
La función FROM_UNIXTIME convierte un timestamp Unix (el número de segundos transcurridos desde el 1 de enero de 1970 a las 00:00:00 UTC) en una fecha y hora legibles. Este tipo de timestamp es el estándar de facto en programación: APIs REST, logs de servidores, bases de datos NoSQL y prácticamente todos los lenguajes de programación lo usan para representar momentos en el tiempo como un simple número entero.
Cuando recibes datos de una API externa, importas logs de servidor o migras datos desde sistemas que almacenan fechas como timestamps Unix, FROM_UNIXTIME es la función que necesitas para convertir esos números en fechas que los humanos pueden leer y que MySQL puede manipular con sus funciones de fecha.
Sintaxis
-- Formato por defecto (YYYY-MM-DD HH:MM:SS)
FROM_UNIXTIME(timestamp_unix)
-- Con formato personalizado
FROM_UNIXTIME(timestamp_unix, formato)El primer argumento es un número entero o decimal que representa los segundos desde la época Unix (1 de enero de 1970, 00:00:00 UTC). El segundo argumento, opcional, es una cadena de formato idéntica a la que usa DATE_FORMAT. Si no se especifica formato, la función devuelve un valor DATETIME; si se especifica, devuelve una cadena formateada.
Comportamiento básico
Veamos cómo FROM_UNIXTIME traduce algunos timestamps conocidos:
SELECT
FROM_UNIXTIME(0) AS epoca,
FROM_UNIXTIME(1000000000) AS mil_millones,
FROM_UNIXTIME(1735689600) AS inicio_2025,
FROM_UNIXTIME(1750000000) AS futuro;| epoca | mil_millones | inicio_2025 | futuro |
|---|---|---|---|
| 1970-01-01 00:00:00 | 2001-09-09 01:46:40 | 2025-01-01 00:00:00 | 2025-06-15 18:26:40 |
El timestamp 0 corresponde al inicio de la época Unix: medianoche del 1 de enero de 1970. El timestamp 1000000000 (mil millones de segundos) fue un momento memorable en la historia de la informática, el 9 de septiembre de 2001. Las fechas de 2025 están en el rango de los 1.7 mil millones.
Fracciones de segundo
FROM_UNIXTIME también acepta valores decimales para representar fracciones de segundo:
SELECT
FROM_UNIXTIME(1735689600.500) AS medio_segundo,
FROM_UNIXTIME(1735689600.123456) AS microsegundos;| medio_segundo | microsegundos |
|---|---|
| 2025-01-01 00:00:00.500000 | 2025-01-01 00:00:00.123456 |
Esta precisión es útil cuando trabajas con datos de alta frecuencia, como logs de rendimiento de aplicaciones o datos de sensores IoT que registran eventos con precisión de milisegundos o microsegundos.
Caso práctico: convertir logs de servidor
Los servidores web y de aplicaciones suelen registrar eventos con timestamps Unix. Si importas estos logs a MySQL, necesitarás convertirlos a fechas legibles para su análisis:
SELECT
evento,
timestamp_unix,
FROM_UNIXTIME(timestamp_unix) AS fecha_hora,
FROM_UNIXTIME(timestamp_unix, '%d/%m/%Y %H:%i') AS formato_europeo
FROM (
SELECT 'login' AS evento, 1735730400 AS timestamp_unix
UNION SELECT 'compra', 1735731200
UNION SELECT 'logout', 1735734800
UNION SELECT 'error_500', 1735738400
) logs;| evento | timestamp_unix | fecha_hora | formato_europeo |
|---|---|---|---|
| login | 1735730400 | 2025-01-01 11:20:00 | 01/01/2025 11:20 |
| compra | 1735731200 | 2025-01-01 11:33:20 | 01/01/2025 11:33 |
| logout | 1735734800 | 2025-01-01 12:33:20 | 01/01/2025 12:33 |
| error_500 | 1735738400 | 2025-01-01 13:33:20 | 01/01/2025 13:33 |
El segundo argumento de FROM_UNIXTIME permite formatear la salida directamente, sin necesidad de encadenar con DATE_FORMAT. Los especificadores de formato son los mismos: %d para día, %m para mes, %Y para año completo, %H para hora en formato 24h y %i para minutos.
Caso práctico: analizar datos de APIs externas
Muchas APIs devuelven fechas como timestamps Unix. Si almacenas esas respuestas en MySQL, puedes usar FROM_UNIXTIME para analizarlas:
SELECT
usuario_id,
FROM_UNIXTIME(created_at) AS fecha_registro,
FROM_UNIXTIME(last_login) AS ultimo_acceso,
DATEDIFF(
FROM_UNIXTIME(last_login),
FROM_UNIXTIME(created_at)
) AS dias_activo
FROM (
SELECT 1001 AS usuario_id, 1704067200 AS created_at, 1735689600 AS last_login
UNION SELECT 1002, 1711929600, 1735603200
UNION SELECT 1003, 1719792000, 1735516800
) usuarios_api;| usuario_id | fecha_registro | ultimo_acceso | dias_activo |
|---|---|---|---|
| 1001 | 2024-01-01 00:00:00 | 2025-01-01 00:00:00 | 366 |
| 1002 | 2024-04-01 00:00:00 | 2024-12-31 00:00:00 | 274 |
| 1003 | 2024-07-01 00:00:00 | 2024-12-30 00:00:00 | 183 |
Una vez convertidos con FROM_UNIXTIME, los timestamps se pueden usar con todas las funciones de fecha de MySQL: DATEDIFF, DATE_FORMAT, YEAR, MONTH, etc.
Caso práctico: filtrar por rangos de fechas con timestamps
Cuando tus datos están almacenados como timestamps Unix pero necesitas filtrar por fechas legibles, tienes dos opciones. Puedes convertir el timestamp en la consulta o convertir las fechas de filtro a timestamps. Ambas funcionan, pero la segunda es más eficiente si hay un índice en la columna de timestamp:
-- Opción 1: convertir el timestamp (no usa índice)
SELECT * FROM eventos_log
WHERE FROM_UNIXTIME(timestamp_evento) BETWEEN '2025-01-01' AND '2025-01-31';
-- Opción 2: convertir las fechas de filtro (usa índice)
SELECT * FROM eventos_log
WHERE timestamp_evento BETWEEN UNIX_TIMESTAMP('2025-01-01') AND UNIX_TIMESTAMP('2025-01-31 23:59:59');La opción 2 es preferible en tablas grandes porque no aplica una función sobre la columna indexada, lo que permite a MySQL usar el índice para acelerar la búsqueda.
Consideraciones de zona horaria
Un aspecto crucial de FROM_UNIXTIME es que convierte el timestamp a la zona horaria de la sesión MySQL actual. El mismo timestamp puede producir fechas diferentes según la zona horaria configurada:
SET time_zone = '+00:00';
SELECT FROM_UNIXTIME(1735689600) AS utc;
SET time_zone = '+01:00';
SELECT FROM_UNIXTIME(1735689600) AS europa_central;
SET time_zone = '-05:00';
SELECT FROM_UNIXTIME(1735689600) AS nueva_york;| utc |
|---|
| 2025-01-01 00:00:00 |
| europa_central |
|---|
| 2025-01-01 01:00:00 |
| nueva_york |
|---|
| 2024-12-31 19:00:00 |
El mismo timestamp (1735689600) se muestra como horas diferentes según la zona horaria. Esto es correcto: el timestamp Unix siempre está en UTC, y FROM_UNIXTIME lo convierte a la zona horaria local. Ten esto en cuenta al comparar datos entre servidores con diferentes configuraciones de zona horaria.
Límites del rango
FROM_UNIXTIME tiene un rango limitado. No puede representar fechas anteriores a la época Unix ni posteriores al año 2038 en sistemas de 32 bits:
SELECT
FROM_UNIXTIME(0) AS minimo,
FROM_UNIXTIME(2147483647) AS maximo_32bit,
FROM_UNIXTIME(-1) AS negativo;| minimo | maximo_32bit | negativo |
|---|---|---|
| 1970-01-01 00:00:00 | 2038-01-19 03:14:07 | NULL |
Los timestamps negativos devuelven NULL en MySQL. El valor máximo en sistemas de 32 bits es 2147483647 (19 de enero de 2038), conocido como el "problema del año 2038". En MySQL de 64 bits, el rango se extiende mucho más allá de esa fecha.
FROM_UNIXTIME con NULL
SELECT FROM_UNIXTIME(NULL) AS resultado;| resultado |
|---|
| NULL |
Combinación con otras funciones
FROM_UNIXTIME se combina frecuentemente con funciones de extracción y agrupación para analizar datos almacenados como timestamps:
SELECT
DATE(FROM_UNIXTIME(timestamp_evento)) AS fecha,
HOUR(FROM_UNIXTIME(timestamp_evento)) AS hora,
COUNT(*) AS total_eventos
FROM (
SELECT 1735730400 AS timestamp_evento
UNION SELECT 1735731200
UNION SELECT 1735734800
UNION SELECT 1735738400
UNION SELECT 1735741200
) eventos
GROUP BY DATE(FROM_UNIXTIME(timestamp_evento)), HOUR(FROM_UNIXTIME(timestamp_evento))
ORDER BY hora;| fecha | hora | total_eventos |
|---|---|---|
| 2025-01-01 | 11 | 2 |
| 2025-01-01 | 12 | 1 |
| 2025-01-01 | 13 | 1 |
| 2025-01-01 | 14 | 1 |
Este patrón es muy habitual cuando analizas datos de telemetría o logs para identificar las horas pico de actividad.
En el siguiente artículo veremos UNIX_TIMESTAMP para el proceso inverso.
Escrito por Eduardo Lázaro
