Como converter um carimbo de data / hora da época em um formato legível por humanos no CLI?

183

Como converter um carimbo de data / hora da época em um formato legível por humanos no CLI? Eu acho que existe uma maneira de fazer isso com a data, mas a sintaxe me escapa (outras formas são bem-vindas).

xenoterracida
fonte

Respostas:

268

Em * BSD:

date -r 1234567890

No Linux (especificamente, com GNU coreutils ≥5.3):

date -d @1234567890

Com versões mais antigas da data GNU, você pode calcular a diferença relativa à época UTC:

date -d '1970-01-01 UTC + 1234567890 seconds'

Se você precisa de portabilidade, está sem sorte. A única hora em que você pode formatar com uma linha de comando do shell POSIX (sem fazer o cálculo sozinho) é a hora atual. Na prática, o Perl está frequentemente disponível:

perl -le 'print scalar localtime $ARGV[0]' 1234567890
Gilles
fonte
4
+1 para o comentário sobre a falta de portabilidade (por que não o POSIX especs incluir uma maneira de fazer isso grr?)
Richard Hansen
3
O que @significa isso date -d @1234567890? man datenão fez nenhuma referência a isso ...
Chris Markle
10
As páginas de manual do @ChrisMarkle GNU geralmente são lamentavelmente incompletas. “O formato da cadeia de datas é mais complexo do que é facilmente documentado aqui, mas está totalmente descrito na documentação informativa
Gilles
2
O info dateé bastante completo. A entrada em 28.9 Seconds since the Epochexplica em detalhes sobre o @timestamp.
No Linux em um pipe: data + '% s' | xargs -I data n -d @n
Ivan Ogai
26

date -d @1190000000 Substitua 1190000000 pela sua época

fschmitt
fonte
8
Supondo que a data do GNU seja.
Gilles
14
$ echo 1190000000 | perl -pe 's/(\d+)/localtime($1)/e' 
Sun Sep 16 20:33:20 2007

Isso pode ser útil para os aplicativos que usam o tempo da época nos arquivos de log:

$ tail -f /var/log/nagios/nagios.log | perl -pe 's/(\d+)/localtime($1)/e'
[Thu May 13 10:15:46 2010] EXTERNAL COMMAND: PROCESS_SERVICE_CHECK_RESULT;HOSTA;check_raid;0;check_raid.pl: OK (Unit 0 on Controller 0 is OK)
Stefan Lasiewski
fonte
11

Formato personalizado com GNU date:

date -d @1234567890 +'%Y-%m-%d %H:%M:%S'

Ou com o GNU awk:

awk 'BEGIN { print strftime("%Y-%m-%d %H:%M:%S", 1234567890); }'

Pergunta SO vinculada: https://stackoverflow.com/questions/3249827/convert-from-unixtime-at-command-line

Ivan Chau
fonte
3
Funciona apenas para a data GNU e o GNU awk. Nem o awk nem o nawk suportam o strftime.
28914 DarkHeart
11

Com bash-4.2ou acima:

printf '%(%F %T)T\n' 1234567890

(onde %F %Testá o strftime()formato -type)

Essa sintaxe é inspirada ksh93.

No ksh93entanto, o argumento é tomado como uma expressão de data em que vários formatos e dificilmente documentados são suportados.

Por um período de época Unix, a sintaxe ksh93é:

printf '%(%F %T)T\n' '#1234567890'

ksh93no entanto, parece usar seu próprio algoritmo para o fuso horário e pode errar. Por exemplo, na Grã-Bretanha, era verão o ano todo em 1970, mas:

$ TZ=Europe/London bash -c 'printf "%(%c)T\n" 0'
Thu 01 Jan 1970 01:00:00 BST
$ TZ=Europe/London ksh93 -c 'printf "%(%c)T\n" "#0"'
Thu Jan  1 00:00:00 1970
Stéphane Chazelas
fonte
7

Se o tempo da época estiver em milissegundos em vez de segundos, remova os três últimos dígitos antes de passá-lo para date -d:

$ date -d @1455086371603
Tue Nov  7 02:46:43 PST 48079     #Incorrect

Isso fornece dados incorretos. Remova os três últimos dígitos.

$ date -d @1455086371
Tue Feb  9 22:39:31 PST 2016      #Correct after removing the last three digits. You may remove and round off the last digit too.
KnockTurnAl
fonte
Que utilitário imprime incluído milissegundos (sem um ponto)?
Vi que o servidor de aplicativos WebLogic geralmente retorna valores de tempo de dados com milissegundos e sem pontos ao usar a ferramenta de script. por exemplo, lastSuccessfulConnectionUse = 1455086371603
KnockTurnAl
Eu vejo. Esta página confirma o valor do tempo bruto O carimbo de data e hora em milissegundos . Obrigado.
As ferramentas Atlassian registram seus registros de data e hora como tempo de época em milissegundos.
Br.Bill
6

Os dois que eu uso com frequência são:

$ perl -leprint\ scalar\ localtime\ 1234567890
Sat Feb 14 00:31:30 2009

e

$ tclsh
% clock format 1234567890
Sa Feb 14 00:31:30 CET 2009
al.
fonte
6

Com zshvocê pode usar o strftimebuiltin:

strftime epochTime formato
Produza 
      a data indicada por epochtime no formato especificado.

por exemplo

zmodload zsh/datetime
strftime '%A, %d %b %Y' 1234567890
Sexta-feira, 13 de fevereiro de 2009

Há também dateconvde dateutils:

dateconv -i '%s' -f '%A, %d %b %Y' 1234567890
Sexta-feira, 13 de fevereiro de 2009

lembre-se de que as dateutilsferramentas padrão são UTC(adicione -z your/timezonese necessário).

don_crissti
fonte
0

Você também pode usar um pequeno programa C para imprimir a data e hora no formato que pode ser analisado diretamente pelo shell

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(int argc, char * argv[]) {

    if (argc==1) { 
        return 1;
    }

    struct tm input_tm;
    char * formatStr  = "YEAR=%Y\nMON=%m\nDAY=%d\nHOUR=%H\nMIN=%M\nSEC=%S";
    size_t formatSize = strlen(formatStr) + 2;
    char * output     = (char *)malloc(sizeof(char)*formatSize);

    strptime(argv[1],"%s",&input_tm);
    strftime(output, formatSize, formatStr, &input_tm);

    printf("%s\n",output);
    free(output);
    return 0;
}

uso:

#compile
clang -o epoch2datetime main.c

#invoke
eval `./epoch2datetime 1450196411`
echo $YEAR $MON $DAY $HOUR $MIN $SEC
#output
#2015 12 16 00 20 11
Miau
fonte
0

Não seria uma solução real sem um pequeno node.js:

epoch2date(){
    node -p "new Date($1)"
}

adicione isso ~/.bash_aliasese verifique se ele é fornecido ~/.bashrccom. ~/.bash_aliases

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

Para obter o nó no seu sistema, vá para http://nvm.sh e execute o comando curl. Ele instalará o gerenciador de versão do nó (nvm), que permite alternar versões do nó.

Basta digitar nvm ls-remotee escolher uma versão para nvm install <version>.

chovy
fonte
0

Existe uma maneira mais fácil de fazer isso: (([System.DateTimeOffset] :: FromUnixTimeMilliSeconds ($ unixtime)). DateTime) .ToString ("s")

Kulwinder Singh
fonte
Bem-vindo ao U&L! Por favor, dê uma olhada nas tags da pergunta: esse código funciona em algum shell em algum sistema Unix ou semelhante ao Unix?
fra-san
Esta técnica está usando o Microsoft .NET. Não parece OP está procurando uma solução MS.
user2320464 20/09