Perintah untuk mendapatkan waktu dalam milidetik

286

Apakah ada perintah shell di Linux untuk mendapatkan waktu dalam milidetik?

MOHAMED
sumber
12
date +%s.%Nakan memberi Anda nanodetik, dapatkah Anda bekerja dengan itu?
Wrikken
1
@Wrikken Namun ini tidak cukup portabel.
Camilo Martin
16
date + "% Y% m% d.% H% M% S% 3N" - Umumnya saya menggunakan perintah ini untuk mendapatkan waktu penuh dan unik hingga mili detik untuk membuat nama file sementara dalam skrip unix bash. Jika sistem Anda tidak dapat mengatasi mili detik, Anda dapat menggunakan mikro atau nano detik masing-masing menggunakan 3 hingga 6 dan 9.
Nitin Mahesh
Cobadate -Ins
Dr. Person Person II

Jawaban:

343

date +%s%N mengembalikan jumlah detik + nanodetik saat ini.

Karena itu, echo $(($(date +%s%N)/1000000))itulah yang Anda butuhkan.

Contoh:

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

date +%s mengembalikan jumlah detik sejak zaman, jika itu berguna.

Alper
sumber
69
tidak berfungsi pada Mac OS, karena %Ntidak didukung olehdate
yegor256
33
Pertanyaannya adalah menanyakan perintah Linux. @ alper's jawaban berfungsi dengan baik untuk perintah tanggal dengan GNU coreutils . GNUtize OSX Anda: Instal dan Gunakan Alat Baris Perintah GNU pada Mac OS X
caligari
77
date +%s%3Nlebih cepat (berdasarkan jawaban @ michael-defort)
caligari
10
Pada OSX Anda perlu menginstal versi tanggal GNU sebagai bagian dari coreutilsmenggunakan MacPorts atau Homebrew - kemudian gunakan gdateperintah. Lihat pertanyaan ini: stackoverflow.com/questions/9804966/…
Pierz
1
Meskipun tanggal +% s% 3N tampaknya lebih mudah atau lebih baik, tetapi menggunakannya dalam beberapa perhitungan offset lainnya menyebabkan timestamp berkurang 1 milidetik! Tetapi solusi ini bekerja sempurna dengan perhitungan offset
Arsinux
341
  • date +"%T.%N" mengembalikan waktu saat ini dengan nanodetik.

    06:46:41.431857000
  • date +"%T.%6N" mengembalikan waktu saat ini dengan nanodetik dibulatkan ke 6 digit pertama, yaitu mikrodetik.

    06:47:07.183172
  • date +"%T.%3N" mengembalikan waktu saat ini dengan nanodetik dibulatkan ke 3 digit pertama, yaitu milidetik.

    06:47:42.773

Secara umum, setiap bidang dalam dateformat perintah dapat diberikan lebar bidang opsional.

Michael Defort
sumber
32
%xN: bagus untuk lebar bidang!
fduff
1
tanggal + "% Y% m% d.% H% M% S% 3N" selama mili detik.
Nitin Mahesh
4
Saya kira ini adalah jawaban yang lebih baik bahwa yang ditandai sebagai yang benar.
kcondezo
74

Nano adalah 10 −9 dan mili 10 −3 . Oleh karena itu, kita dapat menggunakan tiga karakter pertama nanodetik untuk mendapatkan milidetik:

date +%s%3N

Dari man date:

% N nanodetik (000000000..999999999)

% s detik sejak 1970-01-01 00:00:00 UTC

Sumber: Kesalahan Server Bagaimana saya mendapatkan waktu Unix saat ini dalam milidetik di Bash? .

fedorqui 'SO berhenti merugikan'
sumber
Saya merasa sangat bangga bahwa @Peter Mortensen melakukan salah satu bacaan aktifnya yang luar biasa di salah satu posting saya :) terima kasih !!
fedorqui 'SO stop harming'
46

Pada OS X, di mana datetidak mendukung %Nflag, saya sarankan menginstal coreutilsmenggunakan Homebrew . Ini akan memberi Anda akses ke perintah yang disebut gdateyang akan berperilaku seperti datehalnya pada sistem Linux.

brew install coreutils

Untuk pengalaman yang lebih "asli", Anda selalu dapat menambahkan ini ke .bash_aliases:

alias date='gdate'

Kemudian jalankan

$ date +%s%N
Joshua Cook
sumber
10

Berikut ini adalah hack portabel untuk Linux untuk mendapatkan waktu dalam milidetik:

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

Outputnya adalah:

3010

Ini adalah operasi yang sangat murah, yang bekerja dengan internal shell dan procfs.

Bastian Bittorf
sumber
1
Hanya satu yang sejauh ini yang berfungsi pada Xeon Phi BusyBox v1.27.0 (2017-09-27 13:20:28 EDT) MicroOS - dengan senang hati akan menang tiga kali!
Cadoiz
8

date perintah tidak menyediakan mili detik pada OS X, jadi gunakan alias dari python

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

ATAU

alias millis='python -c "import time; print(int(time.time()*1000))"'
Thamme Gowda
sumber
2
... Namun, setelah Anda fork()menghapus proses yang terpisah, execedit juru bahasa Python Anda, biarkan ia memuat perpustakaannya / inisialisasi, tulis hasilnya, dan keluar, hasilnya tidak akan lagi akurat.
Charles Duffy
4

Jawaban lain mungkin cukup dalam banyak kasus, tetapi saya pikir saya akan menambahkan dua sen saya ketika saya mengalami masalah pada sistem BusyBox .

Sistem yang dipermasalahkan tidak mendukung %Nopsi format dan tidak memiliki interpreter Python atau Perl.

Setelah banyak yang menggaruk kepala, kami (terima kasih Dave!) Datang dengan ini:

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

Ini mengekstrak detik dan mikrodetik dari output adjtimex (biasanya digunakan untuk mengatur opsi untuk jam sistem) dan mencetaknya tanpa garis baru (sehingga mereka direkatkan). Perhatikan bahwa bidang mikrodetik harus diisi sebelumnya dengan nol, tetapi ini tidak memengaruhi bidang detik yang lebih panjang dari enam digit. Dari sini harus sepele untuk mengubah mikrodetik menjadi milidetik.

Jika Anda memerlukan garis baru yang tertinggal (mungkin karena terlihat lebih baik) maka cobalah

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

Perhatikan juga bahwa ini memerlukan adjtimexdan awktersedia. Jika tidak maka dengan BusyBox Anda dapat mengarahkannya secara lokal dengan:

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

Dan kemudian sebut di atas sebagai

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

Atau tentu saja Anda bisa memasukkannya ke dalam PATH

EDIT:

Di atas berfungsi pada perangkat BusyBox saya. Di Ubuntu saya mencoba hal yang sama dan menyadari bahwa adjtimexada versi yang berbeda. Di Ubuntu ini berfungsi untuk menghasilkan waktu dalam detik dengan tempat desimal ke mikrodetik (termasuk garis baru yang tertinggal)

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

Saya tidak akan melakukan ini di Ubuntu. Saya akan menggunakandate +%s%N

pghalliday
sumber
Wow, alternatif yang bagus! Memang perintahmu berhasil, tapi aku tidak tahu mengapa. Di mana saya menemukan dokumentasi untuk perintah awk ?! Bagaimana Anda mengetahui cara membuat string untuk mengekstrak informasi yang diinginkan dari output adjtimex?
Satria
Solusi busybox yang luar biasa
Codebling
1

Perl dapat digunakan untuk ini, bahkan pada platform eksotis seperti AIX. Contoh:

#!/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
sumber
1

Skrip Python seperti ini:

import time
cur_time = int(time.time()*1000)
Maoyang
sumber
3
ini tidak akan mengembalikan jumlah milidetik, ini akan mengembalikan jumlah detik yang dinyatakan dalam milidetik. Semuanya akan menjadi $ SECONDS000
kilianc
1
@kilianc maoyang's kode Python menyediakan milidetik.
jlliagre
@ jlliagre: Tetapi apakah resolusi waktu aktual lebih baik dari 16-17 ms (1/60 detik) atau tidak?
Peter Mortensen
Ya, Python time.time()mengembalikan float ke 6 tempat desimal, setidaknya pada MacOS.
porglezomp
1

Saya hanya ingin menambahkan ke jawaban Alper apa yang harus saya lakukan untuk menyelesaikan pekerjaan ini:

Di Mac, Anda perlu brew install coreutils, jadi kami bisa menggunakannya gdate. Kalau tidak di Linux, hanya saja date. Dan fungsi ini akan membantu Anda mengatur waktu tanpa harus membuat file sementara atau apa pun:

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

Dan Anda dapat menggunakannya dengan string:

timeit 'tsc --noEmit'
Chet
sumber
Saya suka solusi ini, tetapi saya lebih tertarik pada millis. Saya mem-porting fungsi ini ke .bashrc saya di ubuntu:function timeit () { start=$(date +%s%N); $*; end=$(date +%s%N); runtime=$(((end-start)/1000000)); echo "$runtime ms" }
Uluaiv
1

Ketika Anda menggunakan GNU AWK sejak versi 4.1, Anda dapat memuat pustaka waktu dan melakukan:

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

Ini akan mencetak waktu saat ini dalam detik sejak 1970-01-01T00: 00: 00 dalam akurasi sub detik.

the_time = gettimeofday() Kembalikan waktu dalam detik yang telah berlalu sejak 1970-01-01 UTC sebagai nilai titik-mengambang. Jika waktu tidak tersedia di platform ini, kembali -1dan atur ERRNO. Waktu yang dikembalikan harus memiliki ketepatan sub-detik , tetapi ketepatan sebenarnya dapat bervariasi berdasarkan pada platform. Jika gettimeofday()panggilan sistem C standar tersedia di platform ini, maka itu hanya mengembalikan nilai. Kalau tidak, jika pada MS-Windows, ia mencoba menggunakannya GetSystemTimeAsFileTime().

Sumber: GNU awk panduan

Pada sistem Linux, fungsi C standar getimeofday()mengembalikan waktu dalam akurasi mikrodetik.

Kvantour
sumber
0

Untuk menampilkan tanggal dengan waktu dan zona waktu

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

Output: 22-04-2020 18: 01: 35.970289239 IST

Anil Agrawal
sumber