Como Converter um Unix Timestamp para uma Data no Linux: date, awk e Scripts Bash

Terminal Linux convertendo um timestamp Unix em data legível usando o comando date

Converter um timestamp do Linux para uma data é algo que você fará constantemente como desenvolvedor ou administrador de sistemas, e o Linux oferece várias maneiras limpas de fazer isso. O método mais rápido é o comando date com a flag -d , mas awk e scripts Bash permitem que você lide com conversões em massa ou incorpore a lógica em automação. Aqui está exatamente como cada abordagem funciona, com exemplos prontos para copiar e colar que você pode executar agora mesmo.

O que é um Timestamp Unix?

Um timestamp Unix é o número de segundos decorridos desde 1º de janeiro de 1970, às 00:00:00 UTC. Este ponto de partida é chamado de época Unix. Então o timestamp 1700000000 significa que 1.700.000.000 segundos se passaram desde esse momento, o que corresponde a 14 de novembro de 2023, às 22:13:20 UTC.

Os timestamps são neutros em relação ao fuso horário por definição. Eles sempre contam a partir da mesma origem UTC, o que os torna ideais para logs, bancos de dados e APIs. A data legível que você vê depende inteiramente de qual fuso horário você aplica durante a conversão. Se você quer uma compreensão mais profunda sobre o que é realmente o tempo de época, o artigo Tempo de Época: A Fundação dos Timestamps Unix cobre o conceito em detalhes.

10 dígitos versus 13 dígitos: Um timestamp Unix padrão tem 10 dígitos (segundos). Um timestamp de 13 dígitos está em milissegundos. O comando date do Linux espera segundos, portanto você precisará remover os últimos três dígitos se estiver trabalhando com milissegundos.

Converter um Timestamp com o Comando date

O comando date é a ferramenta mais rápida para uma conversão única. No Linux (GNU coreutils), a flag -d aceita uma string como @1700000000, onde o prefixo @ diz ao date que você está passando um timestamp Unix.

date -d @1700000000

Saída:

Tue Nov 14 22:13:20 UTC 2023

Você pode controlar o formato de saída usando a sintaxe date +FORMAT. A string de formato segue os especificadores de formato do GNU coreutils. Os mais comuns são:

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

Combinando-os:

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

Saída:

2023-11-14 22:13:20
Usuários de macOS: O comando date no macOS usa sintaxe BSD, não GNU. O equivalente lá é date -r 1700000000. A sintaxe -d @timestamp funciona apenas no Linux com GNU coreutils instalado.

Converter Timestamps em Arquivos Usando awk

Quando você tem um arquivo de log ou CSV com uma coluna de timestamps Unix, awk é a ferramenta certa. Ele permite que você processe cada linha e converta timestamps dinamicamente sem um arquivo de script separado.

Suponha que você tenha um arquivo de log onde o primeiro campo é um timestamp Unix:

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

Esta linha única de awk converte o primeiro campo para uma data legível e imprime o resto da linha:

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

Saída:

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

Se você está trabalhando com um CSV onde o timestamp está em uma coluna específica (digamos coluna 3), ajuste a referência do 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 também possui uma função strftime integrada no gawk (GNU awk), que evita spawnar um subprocess para cada linha. Isto é significativamente mais rápido em arquivos grandes:

gawk '{print strftime("%Y-%m-%d %H:%M:%S", $1), $2, $3}' logfile.txt
gawk versus awk: strftime é uma extensão do gawk. Se seu sistema usa mawk ou nawk (comum em configurações mais antigas de Debian/Ubuntu), pode não estar disponível. Execute awk --version para verificar qual implementação você tem.

Scripts Bash para Conversão de Timestamp

Para lógica reutilizável, uma função Bash ou script supera digitar o mesmo comando repetidamente. Aqui está uma função simples que você pode adicionar ao seu ~/.bashrc ou ~/.bash_profile:

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

Após fazer source do seu perfil ( source ~/.bashrc ), você pode chamá-la assim:

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

Para um script independente que processa um arquivo inteiro e escreve a saída em um novo arquivo:

#!/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"

Torne-o executável e execute-o:

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

Para mais padrões em torno de tratamento de timestamps em scripts e aplicações, o Tutorial de Timestamp Unix para Desenvolvedores: Melhores Práticas cobre casos extremos e erros comuns que valem a pena conhecer.

Lidando com Timestamps em Milissegundos

JavaScript, Java e muitas APIs retornam timestamps de 13 dígitos em milissegundos (como 1700000000000 ). O comando date do Linux entende apenas segundos, portanto você precisa dividir por 1000 primeiro.

Usando aritmética Bash:

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

Ou como uma linha única:

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

No gawk, você pode detectar e lidar com ambos automaticamente:

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

Se você não tem certeza se um timestamp específico está em segundos ou milissegundos, o guia Segundos versus Milissegundos versus Microssegundos: Qual Timestamp Unix Você Deve Usar? explica as diferenças e como identificá-las de forma confiável.

Obtendo o Timestamp Unix Atual no Linux

O comando date +%s imprime o timestamp Unix atual em segundos. Esta é a forma padrão de capturar "agora" como um valor de época em scripts.

date +%s
# Example output: 1700000000

Para milissegundos, multiplique por 1000 usando %3N (nanossegundos truncados para milissegundos):

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

Você também pode armazenar o timestamp atual em uma variável para uso em scripts:

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

Tratamento de Fuso Horário em Conversões

Por padrão, date usa o fuso horário local do seu sistema (definido em /etc/localtime ou através da variável de ambiente TZ ). Para converter para um fuso horário específico sem alterar as configurações do seu sistema, prefixe o comando com uma atribuição 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

Os nomes de fuso horário seguem o formato do Banco de Dados de Fuso Horário da IANA (como America/Chicago ou Europe/London ). Você pode listar todas as zonas disponíveis no seu sistema com:

timedatectl list-timezones

Em um script Bash que precisa lidar com múltiplos fusos horários, defina e cancele TZ explicitamente para evitar efeitos colaterais:

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 uma análise detalhada de como deslocamentos UTC e conversões de fuso horário interagem com timestamps Unix, o artigo Timestamp Unix UTC Explicado: Fusos Horários, Deslocamentos e Conversões mergulha fundo na mecânica.

Tabela de Referência Rápida

Tarefa Comando Observações
Converter timestamp para formato padrão date -d @1700000000 Usa locale e fuso horário do sistema
Converter com formato personalizado date -d @1700000000 "+%Y-%m-%d %H:%M:%S" Saída em estilo ISO
Converter com fuso horário específico TZ="America/New_York" date -d @1700000000 Nenhuma alteração de sistema necessária
Obter timestamp atual date +%s Retorna segundos desde a época
Obter timestamp atual em milissegundos date +%s%3N Saída de 13 dígitos
Converter timestamp em milissegundos date -d "@$((1700000000000 / 1000))" Dividir por 1000 primeiro
Converter em massa com gawk gawk '{print strftime("%Y-%m-%d %H:%M:%S", $1)}' file Rápido, sem subprocess por linha
Interface da ferramenta conversor de timestamp Unix para data

Verifique seu timestamp Linux instantaneamente

Cole qualquer timestamp Unix em nosso conversor gratuito e obtenha a data legível em segundos, milissegundos, ISO 8601 e muito mais formatos simultaneamente. Nenhum comando necessário, detecta automaticamente seu fuso horário e lida com timestamps de 10 dígitos e 13 dígitos.

Verifique seu timestamp Linux instantaneamente →

A sintaxe -d @timestamp é específica do GNU coreutils, que vem em muitas distribuições Linux. Se você está no macOS, FreeBSD ou outro sistema baseado em BSD, o comando date usa sintaxe BSD em vez disso. No macOS, use date -r 1700000000 para obter o mesmo resultado. No Linux, execute date --version para confirmar que você tem GNU coreutils instalado.

Use date -d "2023-11-14 22:13:20" +%s para converter uma string de data legível de volta para um timestamp Unix. O especificador de formato +%s gera segundos desde a época. Você também pode especificar um fuso horário colocando TZ="America/New_York" antes do comando para garantir que a conversão use o deslocamento correto.

date +%s retorna o timestamp Unix atual em segundos (10 dígitos). date +%s%3N acrescenta a parte de milissegundos, dando a você um timestamp de 13 dígitos. O especificador %3N gera os primeiros 3 dígitos do campo de nanossegundos, o que efetivamente fornece precisão de milissegundos. Use a versão de 13 dígitos ao fazer interface com JavaScript, Java ou APIs que esperam milissegundos.

Sim, significativamente. Cada chamada a date dentro de um loop ou do getline do awk spawna um novo subprocess. Em um arquivo com 100.000 linhas, isso significa 100.000 process forks, o que pode levar minutos. gawk strftime funciona inteiramente dentro do processo awk único, tornando-o ordens de magnitude mais rápido para conversões em massa. Sempre prefira gawk strftime ao processar arquivos grandes.

Prefixe o comando date com uma atribuição de variável TZ , como TZ="Europe/London" date -d @1700000000 . Isso substitui o fuso horário do sistema apenas para aquele comando único sem alterar configurações globais. Dentro de um script, envolva isso em uma função que aceita o timestamp e o fuso horário como argumentos para que você possa reutilizá-lo de forma limpa em múltiplas conversões sem efeitos colaterais.

Sim. Use a string de formato "+%FT%T%z" com o comando date : date -d @1700000000 "+%FT%T%z" . Isto gera algo como 2023-11-14T22:13:20+0000 . Para ISO 8601 estrito com dois pontos no deslocamento (como +00:00 ), use "+%FT%T%:z" em vez disso. O especificador %:z adiciona o separador de dois pontos que alguns parsers exigem.