Comando para obter tempo em milissegundos

286

Existe um comando shell no Linux para obter o tempo em milissegundos?

MOHAMED
fonte
12
date +%s.%Ndaria a você nanossegundos, você pode trabalhar com isso?
Wrikken
1
@ Wrikken Isso não é muito portátil.
Camilo Martin
16
date + "% Y% m% d.% H% M% S% 3N" - Geralmente eu uso esse comando para obter o tempo de atualização e o tempo exclusivo de milésimos de segundo para criar os nomes de arquivos temporários no script unix bash. Se o seu sistema não conseguir suportar mili segundos, você poderá ir para micro ou nano segundos usando 3 a 6 e 9, respectivamente.
Nitin Mahesh
Trydate -Ins
Dr. Person Person II

Respostas:

343

date +%s%N retorna o número de segundos + nanossegundos atuais.

Portanto, echo $(($(date +%s%N)/1000000))é o que você precisa.

Exemplo:

$ echo $(($(date +%s%N)/1000000))
1535546718115

date +%s retorna o número de segundos desde a época, se isso for útil.

Alper
fonte
69
não funciona em Mac OS, já que %Nnão é suportado pelodate
yegor256
33
A pergunta está pedindo o comando do Linux. A resposta do @ alper funciona bem para o comando date com o GNU coreutils . GNUtize seu OSX: Instalar e ferramentas de linha de comando Use GNU no Mac OS X
caligari
77
date +%s%3Né mais rápida (resposta baseada na @ de michael-defort)
caligari
10
No OSX, você precisa instalar a versão GNU da data como parte do coreutilsuso do MacPorts ou Homebrew - depois use o gdatecomando Veja esta pergunta: stackoverflow.com/questions/9804966/…
Pierz
1
Embora a data +% s% 3N pareça ser mais fácil ou melhor, mas usá-la em algum outro cálculo de deslocamento fez com que o registro de data e hora fosse reduzido em 1 milissegundo! Mas esta solução funcionou perfeito com o cálculo compensado
Arsinux
341
  • date +"%T.%N" retorna a hora atual em nanossegundos.

    06:46:41.431857000
  • date +"%T.%6N" retorna o horário atual com nanossegundos arredondados para os 6 primeiros dígitos, ou seja, microssegundos.

    06:47:07.183172
  • date +"%T.%3N" retorna o horário atual com nanossegundos arredondados para os três primeiros dígitos, que são milissegundos.

    06:47:42.773

Em geral, todos os campos datedo formato do comando podem receber uma largura de campo opcional.

Michael Defort
fonte
32
%xN: bom para a largura do campo!
Fduff
1
data + "% Y% m% d.% H% M% S% 3N" por mili segundos.
Nitin Mahesh
4
Eu acho que essa é uma resposta melhor que a que está marcada como a correta.
Kcondezo 19/04
74

Nano é 10 −9 e milli 10 −3 . Portanto, podemos usar os três primeiros caracteres de nanossegundos para obter os milissegundos:

date +%s%3N

De man date:

% N nanossegundos (000000000..999999999)

% s segundos desde 1970-01-01 00:00:00 UTC

Fonte: Falha no servidor Como obtenho a hora atual do Unix em milissegundos no Bash? .

fedorqui 'Então pare de prejudicar'
fonte
Sinto-me tão orgulhoso que @Peter Mortensen fez uma de suas excelentes leituras ativas em uma das minhas postagens :) obrigado !!
fedorqui 'Então pare de prejudicar'
46

No OS X, onde datenão suporta o %Nsinalizador, recomendo instalar coreutilsusando o Homebrew . Isso dará acesso a um comando chamado gdateque se comportará como datenos sistemas Linux.

brew install coreutils

Para uma experiência mais "nativa", você sempre pode adicionar isso ao seu .bash_aliases:

alias date='gdate'

Então execute

$ date +%s%N
Joshua Cook
fonte
10

Aqui está um hack portátil de alguma forma portátil para Linux, para obter tempo em milissegundos:

#!/bin/sh
read up rest </proc/uptime; t1="${up%.*}${up#*.}"
sleep 3    # your command
read up rest </proc/uptime; t2="${up%.*}${up#*.}"

millisec=$(( 10*(t2-t1) ))
echo $millisec

A saída é:

3010

Essa é uma operação muito barata, que funciona com shell interns e procfs.

Bastian Bittorf
fonte
1
Até agora, apenas um que funcionasse no Microeon Xi Phi BusyBox v1.27.0 (2017-09-27 13:20:28 EDT) - MicroOS - teria o prazer de votar três vezes!
Cadoiz 7/05/19
8

date O comando não forneceu mili segundos no OS X, então usou um alias do python

millis(){  python -c "import time; print(int(time.time()*1000))"; }

OU

alias millis='python -c "import time; print(int(time.time()*1000))"'
Thamme Gowda
fonte
2
... no entanto, uma vez que você tenha fork()saído de um processo separado, execeditado seu interpretador Python, deixe-o carregar suas bibliotecas / inicialize, escreva seu resultado e saia, esse resultado não será mais preciso.
Charles Duffy
4

As outras respostas provavelmente são suficientes na maioria dos casos, mas pensei em adicionar meus dois centavos quando encontrei um problema em um sistema BusyBox .

O sistema em questão não suportava a %Nopção de formato e não possui nenhum interpretador Python ou Perl.

Depois de muito coçar a cabeça, nós (obrigado Dave!) Chegamos a isso:

adjtimex | awk '/(time.tv_sec|time.tv_usec):/ { printf("%06d", $2) }'

Ele extrai os segundos e microssegundos da saída de adjtimex(normalmente usado para definir opções para o relógio do sistema) e os imprime sem novas linhas (para que sejam colados). Observe que o campo de microssegundos precisa ser preenchido com zeros, mas isso não afeta o campo de segundos, que tem mais de seis dígitos. A partir disso, deve ser trivial converter microssegundos em milissegundos.

Se você precisar de uma nova linha à direita (talvez porque pareça melhor), tente

adjtimex | awk '/(time.tv_sec|time.tv_usec):/ { printf("%06d", $2) }' && printf "\n"

Observe também que isso requer adjtimexe awkestá disponível. Caso contrário, com o BusyBox, você pode apontá-los localmente com:

ln -s /bin/busybox ./adjtimex
ln -s /bin/busybox ./awk

E então chame o acima como

./adjtimex | ./awk '/(time.tv_sec|time.tv_usec):/ { printf("%06d", $2) }'

Ou, é claro, você pode colocá-los no seu PATH

EDITAR:

O acima funcionou no meu dispositivo BusyBox. No Ubuntu, tentei a mesma coisa e percebi que adjtimextem versões diferentes. No Ubuntu, isso funcionou para gerar o tempo em segundos com casas decimais em microssegundos (incluindo uma nova linha à direita)

sudo apt-get install adjtimex
adjtimex -p | awk '/raw time:/ { print $6 }'

Eu não faria isso no Ubuntu embora. eu usariadate +%s%N

pghalliday
fonte
Uau, ótima alternativa! Na verdade, seu comando funciona, mas não tenho idéia do porquê. Onde encontro uma documentação para o comando awk ?! Como diabos você descobriu como construir a string para extrair as informações desejadas da saída adjtimex?
Satria
Solução de busybox impressionante
Codebling
1

O Perl pode ser usado para isso, mesmo em plataformas exóticas como o AIX. Exemplo:

#!/usr/bin/perl -w

use strict;
use Time::HiRes qw(gettimeofday);

my ($t_sec, $usec) = gettimeofday ();
my $msec= int ($usec/1000);

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
    localtime ($t_sec);

printf "%04d-%02d-%02d %02d:%02d:%02d %03d\n",
    1900+$year, 1+$mon, $mday, $hour, $min, $sec, $msec;
Lorinczy Zsigmond
fonte
1

Um script Python como este:

import time
cur_time = int(time.time()*1000)
maoyang
fonte
3
isso não retornará o número de milissegundos, retornará o número de segundos expresso em milissegundos. Tudo será $ SECONDS000
kilianc
1
O código Python do @kilianc maoyang está fornecendo milissegundos.
Jlliagre
@ jlliagre: Mas a resolução de tempo real é melhor que 16-17 ms (1/60 de segundo) ou não?
Peter Mortensen
Sim, o Python time.time()retorna um valor flutuante para 6 casas decimais, pelo menos no macOS.
exemplo
1

Eu só queria acrescentar à resposta de Alper o que eu precisava fazer para que essas coisas funcionassem:

No Mac, você precisará brew install coreutils, para que possamos usá-lo gdate. Caso contrário, no Linux, é apenas date. E essa função o ajudará a cronometrar comandos sem precisar criar arquivos temporários ou qualquer coisa:

function timeit() {
    start=`gdate +%s%N`
    bash -c $1
    end=`gdate +%s%N`
    runtime=$(((end-start)/1000000000.0))
    echo " seconds"
}

E você pode usá-lo com uma string:

timeit 'tsc --noEmit'
Chet
fonte
Eu gosto dessa solução, mas estou mais interessado em milis. Eu portado esta função para o meu .bashrc no ubuntu:function timeit () { start=$(date +%s%N); $*; end=$(date +%s%N); runtime=$(((end-start)/1000000)); echo "$runtime ms" }
Uluaiv 30/01
1

Ao usar o GNU AWK desde a versão 4.1, você pode carregar a biblioteca de tempo e fazer:

$ awk '@load "time"; BEGIN{printf "%.6f", gettimeofday()}'

Isso imprimirá o tempo atual em segundos desde 1970-01-01T00: 00: 00 com precisão de segundo segundo.

the_time = gettimeofday() Retorne o tempo em segundos decorrido desde 01-01-2009 UTC como um valor de ponto flutuante. Se o tempo não estiver disponível nesta plataforma, retorne -1e defina ERRNO. O tempo retornado deve ter precisão de menos de um segundo , mas a precisão real pode variar com base na plataforma. Se a gettimeofday()chamada do sistema C padrão estiver disponível nesta plataforma, ela simplesmente retornará o valor. Caso contrário, se estiver no MS-Windows, ele tenta usar GetSystemTimeAsFileTime().

fonte: manual do GNU awk

Nos sistemas Linux, a função C padrão getimeofday()retorna o tempo com precisão de microssegundos.

kvantour
fonte
0

Para mostrar a data com hora e fuso horário

data + "% d-% m-% Y% T.% N% Z"

Saída: 22-04-2020 18: 01: 35.970289239 IST

Anil Agrawal
fonte