Cómo Convertir un Unix Timestamp a una Fecha en Linux: date, awk, y Scripts Bash

Terminal de Linux convirtiendo un timestamp Unix a fecha legible con el comando date

Convertir una marca de tiempo de Linux a una fecha es algo que harás constantemente como desarrollador o administrador de sistemas, y Linux te ofrece varias formas limpias y directas de hacerlo. El método más rápido es el comando date con la opción -d , pero awk y los scripts de Bash te permiten manejar conversiones en lote o integrar la lógica en tu automatización. Aquí te mostramos exactamente cómo funciona cada enfoque, con ejemplos que puedes copiar y pegar para ejecutar ahora mismo.

¿Qué Es Una Marca De Tiempo Unix?

Una marca de tiempo Unix es el número de segundos que han transcurrido desde el 1 de enero de 1970, a las 00:00:00 UTC. Este punto de partida se llama la época Unix. Así que la marca de tiempo 1700000000 significa que han pasado 1.700.000.000 segundos desde ese momento, lo que corresponde al 14 de noviembre de 2023, a las 22:13:20 UTC.

Las marcas de tiempo son independientes de la zona horaria por definición. Siempre cuentan desde el mismo origen en UTC, lo que las hace ideales para registros, bases de datos y APIs. La fecha legible que ves depende completamente de qué zona horaria apliques durante la conversión. Si quieres profundizar más en qué es realmente el tiempo de época, el artículo Tiempo De Época: El Fundamento De Las Marcas De Tiempo Unix cubre el concepto a fondo.

10 dígitos vs. 13 dígitos: Una marca de tiempo Unix estándar tiene 10 dígitos (segundos). Una marca de tiempo de 13 dígitos está en milisegundos. El comando date de Linux espera segundos, así que tendrás que eliminar los últimos tres dígitos si estás trabajando con milisegundos.

Convertir Una Marca De Tiempo Con El Comando date

El comando date es la herramienta más rápida para una conversión puntual. En Linux (GNU coreutils), la opción -d acepta una cadena como @1700000000, donde el prefijo @ le dice a date que estás pasando una marca de tiempo Unix.

date -d @1700000000

Resultado:

Tue Nov 14 22:13:20 UTC 2023

Puedes controlar el formato de salida usando la sintaxis date +FORMAT. La cadena de formato sigue los especificadores de formato de GNU coreutils. Los más comunes:

  • %Y-%m-%d te da 2023-11-14
  • %H:%M:%S te da 22:13:20
  • %A, %B %d %Y te da Tuesday, November 14 2023
  • %FT%T%z te da el formato ISO 8601: 2023-11-14T22:13:20+0000

Combinándolos:

date -d @1700000000 "+%Y-%m-%d %H:%M:%S"

Resultado:

2023-11-14 22:13:20
Usuarios De macOS: El comando date en macOS usa sintaxis BSD, no GNU. El equivalente allí es date -r 1700000000. La sintaxis -d @timestamp solo funciona en Linux con GNU coreutils instalado.

Convertir Marcas De Tiempo En Archivos Con awk

Cuando tienes un archivo de registro o CSV con una columna de marcas de tiempo Unix, awk es la herramienta indicada. Te permite procesar cada línea y convertir marcas de tiempo sobre la marcha sin necesidad de un archivo de script separado.

Digamos que tienes un archivo de registro donde el primer campo es una marca de tiempo Unix:

1700000000 user=alice action=login
1700003600 user=bob action=logout

Esta línea de awk convierte el primer campo a una fecha legible e imprime el resto de la línea:

awk '{cmd="date -d @"$1" \"+%Y-%m-%d %H:%M:%S\""; cmd | getline d; close(cmd); $1=d; print}' logfile.txt

Resultado:

2023-11-14 22:13:20 user=alice action=login
2023-11-14 23:13:20 user=bob action=logout

Si estás trabajando con un CSV donde la marca de tiempo está en una columna específica (digamos la columna 3), ajusta la referencia de campo:

awk -F',' '{cmd="date -d @"$3" \"+%Y-%m-%d %H:%M:%S\""; cmd | getline d; close(cmd); $3=d; print}' OFS=',' data.csv

awk también tiene una función strftime integrada en gawk (GNU awk), que evita generar un subproceso para cada línea. Esto es significativamente más rápido en archivos grandes:

gawk '{print strftime("%Y-%m-%d %H:%M:%S", $1), $2, $3}' logfile.txt
gawk vs. awk: strftime es una extensión de gawk. Si tu sistema usa mawk o nawk (común en configuraciones antiguas de Debian/Ubuntu), es posible que no esté disponible. Ejecuta awk --version para verificar qué implementación tienes.

Scripts De Bash Para Convertir Marcas De Tiempo

Para lógica reutilizable, una función de Bash o un script supera escribir el mismo comando una y otra vez. Aquí hay una función simple que puedes añadir a tu ~/.bashrc o ~/.bash_profile:

ts2date() {
  date -d "@$1" "+%Y-%m-%d %H:%M:%S %Z"
}

Después de cargar tu perfil ( source ~/.bashrc ), puedes llamarla así:

ts2date 1700000000
# Output: 2023-11-14 22:13:20 UTC

Para un script independiente que procese un archivo completo y escriba la salida en un archivo nuevo:

#!/bin/bash
# convert_timestamps.sh
# Usage: ./convert_timestamps.sh input.txt output.txt

INPUT="$1"
OUTPUT="$2"

while IFS= read -r line; do
  timestamp=$(echo "$line" | awk '{print $1}')
  rest=$(echo "$line" | cut -d' ' -f2-)
  readable=$(date -d "@$timestamp" "+%Y-%m-%d %H:%M:%S")
  echo "$readable $rest"
done < "$INPUT" > "$OUTPUT"

echo "Done. Results written to $OUTPUT"

Hazlo ejecutable y ejecútalo:

chmod +x convert_timestamps.sh
./convert_timestamps.sh logfile.txt converted.txt

Para más patrones relacionados con el manejo de marcas de tiempo en scripts y aplicaciones, el artículo Tutorial De Marcas De Tiempo Unix Para Desarrolladores: Mejores Prácticas cubre casos límite y errores comunes que vale la pena conocer.

Cómo Manejar Marcas De Tiempo En Milisegundos

JavaScript, Java y muchas APIs devuelven marcas de tiempo de 13 dígitos en milisegundos (como 1700000000000 ). El comando date de Linux solo entiende segundos, así que necesitas dividir entre 1000 primero.

Usando aritmética de Bash:

MS_TIMESTAMP=1700000000000
SEC_TIMESTAMP=$((MS_TIMESTAMP / 1000))
date -d "@$SEC_TIMESTAMP" "+%Y-%m-%d %H:%M:%S"

O como una línea única:

date -d "@$((1700000000000 / 1000))" "+%Y-%m-%d %H:%M:%S"

En gawk, puedes detectar y manejar ambas automáticamente:

gawk '{
  ts = $1
  if (length(ts) == 13) ts = int(ts / 1000)
  print strftime("%Y-%m-%d %H:%M:%S", ts), $2, $3
}' logfile.txt

Si no estás seguro de si una marca de tiempo específica está en segundos o milisegundos, la guía Segundos vs Milisegundos vs Microsegundos: ¿Qué Marca De Tiempo Unix Deberías Usar? explica las diferencias y cómo identificarlas de forma fiable.

Obtener La Marca De Tiempo Unix Actual En Linux

El comando date +%s imprime la marca de tiempo Unix actual en segundos. Esta es la forma estándar de capturar "ahora mismo" como un valor de época en scripts.

date +%s
# Example output: 1700000000

Para milisegundos, multiplica por 1000 usando %3N (nanosegundos truncados a milisegundos):

date +%s%3N
# Example output: 1700000000000

También puedes almacenar la marca de tiempo actual en una variable para usarla en scripts:

NOW=$(date +%s)
echo "Script started at: $(date -d @$NOW "+%Y-%m-%d %H:%M:%S")"

Manejo De Zonas Horarias En Las Conversiones

Por defecto, date usa la zona horaria local de tu sistema (configurada en /etc/localtime o a través de la variable de entorno TZ ). Para convertir a una zona horaria específica sin cambiar la configuración de tu sistema, antepón al comando una asignación TZ :

# Convert to New York time
TZ="America/New_York" date -d @1700000000 "+%Y-%m-%d %H:%M:%S %Z"
# Output: 2023-11-14 17:13:20 EST

# Convert to Tokyo time
TZ="Asia/Tokyo" date -d @1700000000 "+%Y-%m-%d %H:%M:%S %Z"
# Output: 2023-11-15 07:13:20 JST

Los nombres de zona horaria siguen el formato de la Base De Datos De Zonas Horarias De IANA (como America/Chicago o Europe/London ). Puedes listar todas las zonas disponibles en tu sistema con:

timedatectl list-timezones

En un script de Bash que necesita manejar múltiples zonas horarias, configura y desconfigura TZ explícitamente para evitar efectos secundarios:

convert_with_tz() {
  local ts="$1"
  local tz="$2"
  TZ="$tz" date -d "@$ts" "+%Y-%m-%d %H:%M:%S %Z"
}

convert_with_tz 1700000000 "Europe/Berlin"
# Output: 2023-11-14 23:13:20 CET

Para un análisis profundo de cómo los desplazamientos de UTC y las conversiones de zona horaria interactúan con las marcas de tiempo Unix, el artículo Marcas De Tiempo Unix Y UTC Explicadas: Zonas Horarias, Desplazamientos Y Conversiones profundiza en los mecanismos.

Tabla De Referencia Rápida

Tarea Comando Notas
Convertir marca de tiempo al formato predeterminado date -d @1700000000 Usa la zona horaria y configuración regional del sistema
Convertir con formato personalizado date -d @1700000000 "+%Y-%m-%d %H:%M:%S" Salida de estilo ISO
Convertir con zona horaria específica TZ="America/New_York" date -d @1700000000 Sin necesidad de cambiar el sistema
Obtener marca de tiempo actual date +%s Devuelve segundos desde la época
Obtener marca de tiempo actual en milisegundos date +%s%3N Salida de 13 dígitos
Convertir marca de tiempo en milisegundos date -d "@$((1700000000000 / 1000))" Divide entre 1000 primero
Conversión en lote con gawk gawk '{print strftime("%Y-%m-%d %H:%M:%S", $1)}' file Rápido, sin subproceso por línea
Interfaz de la herramienta convertidor de marca de tiempo Unix a fecha

Verifica tu marca de tiempo de Linux al instante

Pega cualquier marca de tiempo Unix en nuestro convertidor gratuito y obtén la fecha legible en segundos, milisegundos, ISO 8601 y más formatos simultáneamente. Sin comandos necesarios, detecta automáticamente tu zona horaria y maneja marcas de tiempo de 10 dígitos y 13 dígitos.

Verifica tu marca de tiempo de Linux al instante →

La sintaxis -d @timestamp es específica de GNU coreutils, que se incluye en la mayoría de distribuciones de Linux. Si estás en macOS, FreeBSD u otro sistema basado en BSD, el comando date usa sintaxis BSD en su lugar. En macOS, usa date -r 1700000000 para lograr el mismo resultado. En Linux, ejecuta date --version para confirmar que tienes GNU coreutils instalado.

Usa date -d "2023-11-14 22:13:20" +%s para convertir una cadena de fecha legible de vuelta a una marca de tiempo Unix. El especificador de formato +%s devuelve segundos desde la época. También puedes especificar una zona horaria antecediendo TZ="America/New_York" al comando para asegurarte de que la conversión usa el desplazamiento correcto.

date +%s devuelve la marca de tiempo Unix actual en segundos (10 dígitos). date +%s%3N añade la porción de milisegundos, dándote una marca de tiempo de 13 dígitos. El especificador %3N devuelve los primeros 3 dígitos del campo de nanosegundos, lo que efectivamente te da precisión de milisegundos. Usa la versión de 13 dígitos cuando estés interfazando con JavaScript, Java o APIs que esperen milisegundos.

Sí, significativamente. Cada llamada a date dentro de un bucle o en la función getline de awk genera un nuevo subproceso. En un archivo con 100.000 líneas, eso significa 100.000 bifurcaciones de proceso, lo que puede tomar minutos. gawk strftime se ejecuta completamente dentro del único proceso awk, haciéndolo órdenes de magnitud más rápido para conversiones en lote. Siempre prefiere gawk strftime al procesar archivos grandes.

Antepón al comando date una asignación de variable TZ como TZ="Europe/London" date -d @1700000000 . Esto anula la zona horaria del sistema para ese único comando sin cambiar la configuración global. Dentro de un script, envuelve esto en una función que acepte la marca de tiempo y la zona horaria como argumentos para que puedas reutilizarla de forma limpia en múltiples conversiones sin efectos secundarios.

Sí. Usa la cadena de formato "+%FT%T%z" con el comando date : date -d @1700000000 "+%FT%T%z" . Esto devuelve algo como 2023-11-14T22:13:20+0000 . Para ISO 8601 estricto con dos puntos en el desplazamiento (como +00:00 ), usa "+%FT%T%:z" en su lugar. El especificador %:z añade el separador de dos puntos que algunos analizadores requieren.