Pada catatan lain, tidak bisakah Anda menggunakan timeperintah?
anishsane
Gunakan waktu unix date +%s,, lalu kurangi untuk mendapatkan perbedaan dalam hitungan detik.
roblogic
Jawaban:
476
Bash memiliki SECONDSvariabel bawaan berguna yang melacak jumlah detik yang telah berlalu sejak shell dimulai. Variabel ini mempertahankan sifat-sifatnya ketika ditugaskan ke, dan nilai yang dikembalikan setelah penugasan adalah jumlah detik sejak penugasan ditambah nilai yang diberikan.
Dengan demikian, Anda bisa mengatur SECONDSke 0 sebelum memulai acara waktunya, cukup membaca SECONDSsetelah acara, dan lakukan aritmatika waktu sebelum menampilkan.
SECONDS=0# do some work
duration=$SECONDS
echo "$(($duration / 60)) minutes and $(($duration % 60)) seconds elapsed."
Karena solusi ini tidak bergantung pada date +%s(yang merupakan ekstensi GNU), ini portabel untuk semua sistem yang didukung oleh Bash.
+1. Kebetulan, Anda bisa mengelabui datemelakukan aritmatika waktu untuk Anda, dengan menulis date -u -d @"$diff" +'%-Mm %-Ss'. (Itu ditafsirkan $diffsebagai detik-sejak-zaman, dan menghitung menit dan detik dalam UTC.) Itu mungkin tidak lagi lebih elegan, meskipun, lebih baik dikaburkan. :-P
ruakh
13
Bagus dan sederhana. Jika seseorang membutuhkan jam:echo "$(($diff / 3600)) hours, $((($diff / 60) % 60)) minutes and $(($diff % 60)) seconds elapsed."
chus
6
Ini harus dibaca $(date -u +%s)untuk mencegah kondisi balapan pada tanggal di mana waktu musim panas dihidupkan. Dan waspadai detik-detik lompatan jahat;)
Tino
3
@ daniel-kamil-kozar Nice find. Namun ini agak rapuh. Hanya ada satu variabel seperti itu, sehingga tidak dapat digunakan secara rekursif untuk mengukur kinerja, dan bahkan lebih buruk, setelah unset SECONDSitu hilang:echo $SECONDS; unset SECONDS; SECONDS=0; sleep 3; echo $SECONDS
Tino
6
@ParthianShot: Saya minta maaf karena Anda pikir begitu. Namun, saya percaya bahwa jawaban ini adalah yang dibutuhkan kebanyakan orang saat mencari jawaban untuk pertanyaan seperti ini: untuk mengukur berapa banyak waktu yang berlalu di antara peristiwa, bukan untuk menghitung waktu.
Daniel Kamil Kozar
99
Detik
Untuk mengukur waktu yang berlalu (dalam detik) kita perlu:
bilangan bulat yang mewakili hitungan detik yang berlalu dan
cara untuk mengkonversi bilangan bulat tersebut ke format yang dapat digunakan.
Nilai integer detik yang berlalu:
Ada dua cara internal bash untuk menemukan nilai integer untuk jumlah detik yang berlalu:
Bash variabel DETIK (jika DETIK tidak disetel itu kehilangan properti khusus).
Mengatur nilai DETIK ke 0:
SECONDS=0
sleep 1# Process to execute
elapsedseconds=$SECONDS
Menyimpan nilai variabel SECONDSdi awal:
a=$SECONDS
sleep 1# Process to execute
elapsedseconds=$(( SECONDS - a ))
Opsi Bash printf %(datefmt)T:
a="$(TZ=UTC0 printf '%(%s)T\n' '-1')"### `-1` is the current time
sleep 1### Process to execute
elapsedseconds=$(( $(TZ=UTC0 printf '%(%s)T\n''-1')- a ))
Konversikan bilangan bulat tersebut ke format yang dapat digunakan
Bash internal printfdapat melakukannya secara langsung:
%(FORMAT)Tmenghasilkan string tanggal-waktu yang dihasilkan dari menggunakan FORMAT sebagai string format untuk strftime(3). Argumen terkait adalah jumlah detik sejak Epoch , atau -1 (waktu saat ini) atau -2 (waktu startup shell). Jika tidak ada argumen yang sesuai yang diberikan, waktu saat ini digunakan sebagai standar.
Jadi, Anda mungkin ingin menelepon di textifyDuration $elpasedsecondsmana saja textifyDurationimplementasi lain dari pencetakan durasi:
Untuk mendapatkan waktu yang diformat, kita harus menggunakan alat eksternal (tanggal GNU) dalam beberapa cara untuk mendapatkan hingga hampir satu tahun dan termasuk Nanoseconds.
Matematika di dalam tanggal.
Tidak perlu untuk aritmatika eksternal, lakukan semuanya dalam satu langkah di dalam date:
date -u -d "0 $FinalDate seconds - $StartDate seconds"+"%H:%M:%S"
Ya, ada 0nol dalam string perintah. Itu dibutuhkan.
Itu dengan asumsi Anda bisa mengubah date +"%T"perintah ke date +"%s"perintah sehingga nilai akan disimpan (dicetak) dalam hitungan detik.
Perhatikan bahwa perintah ini terbatas pada:
Nilai positif $StartDatedan $FinalDatedetik.
Nilai dalam $FinalDatelebih besar (nanti dalam waktu) daripada $StartDate.
Perbedaan waktu lebih kecil dari 24 jam.
Anda menerima format output dengan Jam, Menit dan Detik. Sangat mudah diubah.
Dapat diterima untuk menggunakan waktu -u UTC. Untuk menghindari "DST" dan koreksi waktu setempat.
Jika Anda harus menggunakan 10:33:56string, yah, ubah saja menjadi detik,
juga, kata detik dapat disingkat menjadi detik:
Jika diharuskan untuk menghitung perbedaan waktu yang lebih lama (hingga 364 hari), kami harus menggunakan awal (beberapa) tahun sebagai referensi dan nilai format %j(jumlah hari dalam tahun):
Mirip dengan:
string1="+10 days 10:33:56.5400022"
string2="+35 days 10:36:10.8800056"StartDate=$(date -u -d "2000/1/1 $string1"+"%s.%N")FinalDate=$(date -u -d "2000/1/1 $string2"+"%s.%N")
date -u -d "2000/1/1 $FinalDate sec - $StartDate sec"+"%j days %H:%M:%S.%N"Output:026 days 00:02:14.340003400
Sayangnya, dalam hal ini, kita perlu secara manual mengurangi 1SATU dari jumlah hari. Perintah tanggal melihat hari pertama tahun ini sebagai 1. Tidak terlalu sulit ...
Alat yang digunakan pada perangkat yang lebih kecil (executable yang sangat kecil untuk diinstal): Busybox.
Buat tautan ke busybox bernama tanggal:
$ ln -s /bin/busybox date
Gunakan kemudian dengan memanggil ini date(letakkan di direktori PATH termasuk).
Atau buat alias seperti:
$ alias date='busybox date'
Tanggal Busybox memiliki opsi yang bagus: -D untuk menerima format waktu input. Itu membuka banyak format untuk digunakan sebagai waktu. Menggunakan opsi -D kita dapat mengonversi waktu 10:33:56 secara langsung:
date -D "%H:%M:%S"-d "10:33:56"+"%Y.%m.%d-%H:%M:%S"
Dan seperti yang Anda lihat dari output Komando di atas, hari itu dianggap "hari ini". Untuk mendapatkan waktu mulai dari zaman:
$ string1="10:33:56"
$ date -u -D "%Y.%m.%d-%H:%M:%S"-d "1970.01.01-$string1"+"%Y.%m.%d-%H:%M:%S"1970.01.01-10:33:56
Tanggal Busybox bahkan dapat menerima waktu (dalam format di atas) tanpa -D:
$ date -u -d "1970.01.01-$string1"+"%Y.%m.%d-%H:%M:%S"1970.01.01-10:33:56
Dan format output bahkan bisa menjadi detik sejak zaman.
$ date -u -d "1970.01.01-$string1"+"%s"52436
Untuk kedua kali, dan sedikit matematika bash (busybox belum dapat melakukan matematika, belum):
Ini adalah jawaban yang luar biasa meliputi banyak pangkalan dan dengan penjelasan yang bagus. Terima kasih!
Devy
Saya harus mencari %(FORMAT)Tstring yang diteruskan ke printfperintah yang terintegrasi dalam bash. Dari bash-hackers.org : %(FORMAT)Toutput string tanggal-waktu yang dihasilkan dari penggunaan FORMATsebagai string format untuk strftime (3). Argumen terkait adalah jumlah detik sejak Epoch, atau -1 (waktu saat ini) atau -2 (waktu startup shell). Jika tidak ada argumen yang sesuai adalah persediaan, waktu saat ini digunakan sebagai standar . Itu esoteris. Dalam hal ini, %ssebagaimana diberikan strftime(3)adalah "jumlah detik sejak zaman".
Apa bedanya dengan solusi saya? Saya benar-benar tidak dapat melihat manfaat dari memanggil awkdalam kasus ini, karena Bash menangani bilangan aritmatika sama baiknya.
Daniel Kamil Kozar
1
Jawaban Anda juga benar. Beberapa orang, seperti saya, lebih suka bekerja dengan awk daripada dengan bash inconsistencies.
Dorian
2
Bisakah Anda menguraikan lebih lanjut tentang inkonsistensi dalam Bash tentang aritmatika integer? Saya ingin tahu lebih banyak tentang ini, karena saya tidak menyadarinya.
Daniel Kamil Kozar
12
Saya hanya mencari ini. Saya tidak mengerti kritik atas jawaban ini. Saya suka melihat lebih dari satu solusi untuk suatu masalah. Dan, saya salah satu yang lebih suka awkperintah untuk bash (jika tidak untuk yang lain, karena awk bekerja di shell lain). Saya lebih menyukai solusi ini. Tapi itu pendapat pribadi saya.
Saya mencari sesuatu seperti date metode GNU Anda . Jenius.
Haohmaru
Silakan hapus komentar saya ... maaf
Bill Gale
Setelah menginstal dateutilsmelalui apt, tidak ada datediffperintah - harus digunakan dateutils.ddiff.
Suzana
12
Saya ingin mengusulkan cara lain yang menghindari mengingat dateperintah. Mungkin bermanfaat jika Anda telah mengumpulkan cap waktu dalam %Tformat tanggal:
ts_get_sec(){
read -r h m s <<< $(echo $1 | tr ':'' ')
echo $(((h*60*60)+(m*60)+s))}
start_ts=10:33:56
stop_ts=10:36:10
START=$(ts_get_sec $start_ts)
STOP=$(ts_get_sec $stop_ts)
DIFF=$((STOP-START))
echo "$((DIFF/60))m $((DIFF%60))s"
kita bahkan dapat menangani milidetik dengan cara yang sama.
ts_get_msec(){
read -r h m s ms <<< $(echo $1 | tr '.:'' ')
echo $(((h*60*60*1000)+(m*60*1000)+(s*1000)+ms))}
start_ts=10:33:56.104
stop_ts=10:36:10.102
START=$(ts_get_msec $start_ts)
STOP=$(ts_get_msec $stop_ts)
DIFF=$((STOP-START))
min=$((DIFF/(60*1000)))
sec=$(((DIFF%(60*1000))/1000))
ms=$(((DIFF%(60*1000))%1000))
echo "${min}:${sec}.$ms"
Apakah ada cara untuk menangani milidetik, mis. 10: 33: 56.104
Umesh Rajbhandari
Milidetik menangani perilaku buruk jika bidang milidetik dimulai dengan nol. Misalnya ms = "033" akan memberikan digit tambahan "027" karena bidang ms ditafsirkan sebagai oktal. mengubah "echo" ... "+ ms))" menjadi ... "+ $ {ms ## + (0)}))" akan memperbaikinya selama "shopt -s extglob" muncul di suatu tempat di atas ini di naskah. Seseorang mungkin harus menghapus nol terkemuka dari h, m, dan juga ...
Eric Towers
3
echo $(((60*60*$((10#$h)))+(60*$((10#$m)))+$((10#$s))))bekerja untuk saya sejak saya dapatkanvalue too great for base (error token is "08")
Niklas
6
Inilah beberapa keajaiban:
time1=14:30
time2=$( date +%H:%M )# 16:00
diff=$( echo "$time2 - $time1"| sed 's%:%+(1/60)*%g'| bc -l )
echo $diff hours
# outputs 1.5 hours
sedmengganti a :dengan formula untuk dikonversi ke 1/60. Kemudian perhitungan waktu yang dilakukan olehbc
Berikut adalah solusi hanya menggunakan datekemampuan perintah menggunakan "lalu", dan tidak menggunakan variabel kedua untuk menyimpan waktu selesai:
#!/bin/bash# save the current time
start_time=$( date +%s.%N )# tested program
sleep 1# the current time after the program has finished# minus the time when we started, in seconds.nanoseconds
elapsed_time=$( date +%s.%N --date="$start_time seconds ago")
echo elapsed_time: $elapsed_time
Beberapa pemrosesan string dapat menghapus nilai-nilai kosong itu
date -ujf%s $(($(date -jf%T "10:36:10"+%s)- $(date -jf%T "10:33:56"+%s))) \
+'%-Hh %-Mm %-Ss'| sed "s/[[:<:]]0[hms] *//g"# 2m 14s
Ini tidak akan berfungsi jika Anda menempatkan waktu lebih dulu. Jika Anda perlu mengatasinya, ubah $(($(date ...) - $(date ...)))ke$(echo $(date ...) - $(date ...) | bc | tr -d -)
$ units
2411 units,71 prefixes,33 nonlinear units
You have:(10hr+36min+10s)-(10hr+33min+56s)You want: s
*134/0.0074626866You have:(10hr+36min+10s)-(10hr+33min+56s)You want: min
*2.2333333/0.44776119
Saya menyadari ini adalah posting yang lebih tua, tetapi saya menemukan hari ini ketika mengerjakan sebuah skrip yang akan mengambil tanggal dan waktu dari file log dan menghitung delta. Script di bawah ini pasti berlebihan, dan saya sangat merekomendasikan memeriksa logika dan matematika saya.
#!/bin/bash
dTime=""
tmp=""#firstEntry="$(head -n 1 "$LOG" | sed 's/.*] \([0-9: -]\+\).*/\1/')"
firstEntry="2013-01-16 01:56:37"#lastEntry="$(tac "$LOG" | head -n 1 | sed 's/.*] \([0-9: -]\+\).*/\1/')"
lastEntry="2014-09-17 18:24:02"# I like to make the variables easier to parse
firstEntry="${firstEntry//-/ }"
lastEntry="${lastEntry//-/ }"
firstEntry="${firstEntry//:/ }"
lastEntry="${lastEntry//:/ }"# remove the following lines in production
echo "$lastEntry"
echo "$firstEntry"# compute days in last entryfor i in`seq 1 $(echo $lastEntry|awk '{print $2}')`;do{case"$i"in1|3|5|7|8|10|12)
dTime=$(($dTime+31));;4|6|9|11)
dTime=$(($dTime+30));;2)
dTime=$(($dTime+28));;esac}done# do leap year calculations for all years between first and last entryfor i in`seq $(echo $firstEntry|awk '{print $1}') $(echo $lastEntry|awk '{print $1}')`;do{if[ $(($i%4))-eq 0]&&[ $(($i%100))-eq 0]&&[ $(($i%400))-eq 0];then{if["$i"="$(echo $firstEntry|awk '{print $1}')"]&&[ $(echo $firstEntry|awk '{print $2}')-lt 2];then{
dTime=$(($dTime+1))}elif[ $(echo $firstEntry|awk '{print $2}')-eq 2]&&[ $(echo $firstEntry|awk '{print $3}')-lt 29];then{
dTime=$(($dTime+1))}fi}elif[ $(($i%4))-eq 0]&&[ $(($i%100))-ne 0];then{if["$i"="$(echo $lastEntry|awk '{print $1}')"]&&[ $(echo $lastEntry|awk '{print $2}')-gt 2];then{
dTime=$(($dTime+1))}elif[ $(echo $lastEntry|awk '{print $2}')-eq 2]&&[ $(echo $lastEntry|awk '{print $3}')-ne 29];then{
dTime=$(($dTime+1))}fi}fi}done# substract days in first entryfor i in`seq 1 $(echo $firstEntry|awk '{print $2}')`;do{case"$i"in1|3|5|7|8|10|12)
dTime=$(($dTime-31));;4|6|9|11)
dTime=$(($dTime-30));;2)
dTime=$(($dTime-28));;esac}done
dTime=$(($dTime+$(echo $lastEntry|awk '{print $3}')-$(echo $firstEntry|awk '{print $3}')))# The above gives number of days for sample. Now we need hours, minutes, and seconds# As a bit of hackery I just put the stuff in the best order for use in a for loop
dTime="$(($(echo $lastEntry|awk '{print $6}')-$(echo $firstEntry|awk '{print $6}'))) $(($(echo $lastEntry|awk '{print $5}')-$(echo $firstEntry|awk '{print $5}'))) $(($(echo $lastEntry|awk '{print $4}')-$(echo $firstEntry|awk '{print $4}'))) $dTime"
tmp=1for i in $dTime;do{if[ $i -lt 0];then{case"$tmp"in1)
tmp="$(($(echo $dTime|awk '{print $1}')+60)) $(($(echo $dTime|awk '{print $2}')-1))"
dTime="$tmp $(echo $dTime|awk '{print $3""$4}')"
tmp=1;;2)
tmp="$(($(echo $dTime|awk '{print $2}')+60)) $(($(echo $dTime|awk '{print $3}')-1))"
dTime="$(echo $dTime|awk '{print $1}') $tmp $(echo $dTime|awk '{print $4}')"
tmp=2;;3)
tmp="$(($(echo $dTime|awk '{print $3}')+24)) $(($(echo $dTime|awk '{print $4}')-1))"
dTime="$(echo $dTime|awk '{print $1""$2}') $tmp"
tmp=3;;esac}fi
tmp=$(($tmp+1))}done
echo "The sample time is $(echo $dTime|awk '{print $4}') days, $(echo $dTime|awk '{print $3}') hours, $(echo $dTime|awk '{print $2}') minutes, and $(echo $dTime|awk '{print $1}') seconds."
Anda akan mendapatkan output sebagai berikut.
2012101601563720140917182402The sample time is 700 days,16 hours,27 minutes, and 25 seconds.
Saya memodifikasi skrip sedikit untuk membuatnya mandiri (mis. Hanya mengatur nilai variabel), tapi mungkin ide umum juga muncul. Anda mungkin ingin beberapa kesalahan tambahan memeriksa nilai negatif.
Inilah implementasi bash saya (dengan bit diambil dari SO lainnya ;-)
function countTimeDiff(){
timeA=$1 # 09:59:35
timeB=$2 # 17:32:55# feeding variables by using read and splitting with IFS
IFS=: read ah am as <<<"$timeA"
IFS=: read bh bm bs <<<"$timeB"# Convert hours to minutes.# The 10# is there to avoid errors with leading zeros# by telling bash that we use base 10
secondsA=$((10#$ah*60*60 + 10#$am*60 + 10#$as))
secondsB=$((10#$bh*60*60 + 10#$bm*60 + 10#$bs))
DIFF_SEC=$((secondsB - secondsA))
echo "The difference is $DIFF_SEC seconds.";
SEC=$(($DIFF_SEC%60))
MIN=$((($DIFF_SEC-$SEC)%3600/60))
HRS=$((($DIFF_SEC-$MIN*60)/3600))
TIME_DIFF="$HRS:$MIN:$SEC";
echo $TIME_DIFF;}
$ countTimeDiff 2:15:552:55:16The difference is 2361 seconds.0:39:21
time
perintah?date +%s
,, lalu kurangi untuk mendapatkan perbedaan dalam hitungan detik.Jawaban:
Bash memiliki
SECONDS
variabel bawaan berguna yang melacak jumlah detik yang telah berlalu sejak shell dimulai. Variabel ini mempertahankan sifat-sifatnya ketika ditugaskan ke, dan nilai yang dikembalikan setelah penugasan adalah jumlah detik sejak penugasan ditambah nilai yang diberikan.Dengan demikian, Anda bisa mengatur
SECONDS
ke 0 sebelum memulai acara waktunya, cukup membacaSECONDS
setelah acara, dan lakukan aritmatika waktu sebelum menampilkan.Karena solusi ini tidak bergantung pada
date +%s
(yang merupakan ekstensi GNU), ini portabel untuk semua sistem yang didukung oleh Bash.sumber
date
melakukan aritmatika waktu untuk Anda, dengan menulisdate -u -d @"$diff" +'%-Mm %-Ss'
. (Itu ditafsirkan$diff
sebagai detik-sejak-zaman, dan menghitung menit dan detik dalam UTC.) Itu mungkin tidak lagi lebih elegan, meskipun, lebih baik dikaburkan. :-Pecho "$(($diff / 3600)) hours, $((($diff / 60) % 60)) minutes and $(($diff % 60)) seconds elapsed."
$(date -u +%s)
untuk mencegah kondisi balapan pada tanggal di mana waktu musim panas dihidupkan. Dan waspadai detik-detik lompatan jahat;)unset SECONDS
itu hilang:echo $SECONDS; unset SECONDS; SECONDS=0; sleep 3; echo $SECONDS
Detik
Untuk mengukur waktu yang berlalu (dalam detik) kita perlu:
Nilai integer detik yang berlalu:
Ada dua cara internal bash untuk menemukan nilai integer untuk jumlah detik yang berlalu:
Bash variabel DETIK (jika DETIK tidak disetel itu kehilangan properti khusus).
Mengatur nilai DETIK ke 0:
Menyimpan nilai variabel
SECONDS
di awal:Opsi Bash printf
%(datefmt)T
:Konversikan bilangan bulat tersebut ke format yang dapat digunakan
Bash internal
printf
dapat melakukannya secara langsung:demikian pula
tetapi ini akan gagal untuk durasi lebih dari 24 jam, karena kami benar-benar mencetak waktu jam dinding, bukan durasi:
Untuk pecinta detail, dari bash-hackers.org :
Jadi, Anda mungkin ingin menelepon di
textifyDuration $elpasedseconds
mana sajatextifyDuration
implementasi lain dari pencetakan durasi:Tanggal GNU.
Untuk mendapatkan waktu yang diformat, kita harus menggunakan alat eksternal (tanggal GNU) dalam beberapa cara untuk mendapatkan hingga hampir satu tahun dan termasuk Nanoseconds.
Matematika di dalam tanggal.
Tidak perlu untuk aritmatika eksternal, lakukan semuanya dalam satu langkah di dalam
date
:Ya, ada
0
nol dalam string perintah. Itu dibutuhkan.Itu dengan asumsi Anda bisa mengubah
date +"%T"
perintah kedate +"%s"
perintah sehingga nilai akan disimpan (dicetak) dalam hitungan detik.Perhatikan bahwa perintah ini terbatas pada:
$StartDate
dan$FinalDate
detik.$FinalDate
lebih besar (nanti dalam waktu) daripada$StartDate
.Jika Anda harus menggunakan
10:33:56
string, yah, ubah saja menjadi detik,juga, kata detik dapat disingkat menjadi detik:
Perhatikan bahwa konversi waktu detik (seperti yang disajikan di atas) relatif terhadap awal hari "ini" (Hari ini).
Konsepnya dapat diperluas hingga nanodetik, seperti ini:
Jika diharuskan untuk menghitung perbedaan waktu yang lebih lama (hingga 364 hari), kami harus menggunakan awal (beberapa) tahun sebagai referensi dan nilai format
%j
(jumlah hari dalam tahun):Mirip dengan:
Sayangnya, dalam hal ini, kita perlu secara manual mengurangi
1
SATU dari jumlah hari. Perintah tanggal melihat hari pertama tahun ini sebagai 1. Tidak terlalu sulit ...Penggunaan jumlah detik yang lama adalah valid dan didokumentasikan di sini:
https://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html#Examples-of-date
Tanggal kotak bus
Alat yang digunakan pada perangkat yang lebih kecil (executable yang sangat kecil untuk diinstal): Busybox.
Buat tautan ke busybox bernama tanggal:
Gunakan kemudian dengan memanggil ini
date
(letakkan di direktori PATH termasuk).Atau buat alias seperti:
Tanggal Busybox memiliki opsi yang bagus: -D untuk menerima format waktu input. Itu membuka banyak format untuk digunakan sebagai waktu. Menggunakan opsi -D kita dapat mengonversi waktu 10:33:56 secara langsung:
Dan seperti yang Anda lihat dari output Komando di atas, hari itu dianggap "hari ini". Untuk mendapatkan waktu mulai dari zaman:
Tanggal Busybox bahkan dapat menerima waktu (dalam format di atas) tanpa -D:
Dan format output bahkan bisa menjadi detik sejak zaman.
Untuk kedua kali, dan sedikit matematika bash (busybox belum dapat melakukan matematika, belum):
Atau diformat:
sumber
%(FORMAT)T
string yang diteruskan keprintf
perintah yang terintegrasi dalam bash. Dari bash-hackers.org :%(FORMAT)T
output string tanggal-waktu yang dihasilkan dari penggunaanFORMAT
sebagai string format untuk strftime (3). Argumen terkait adalah jumlah detik sejak Epoch, atau -1 (waktu saat ini) atau -2 (waktu startup shell). Jika tidak ada argumen yang sesuai adalah persediaan, waktu saat ini digunakan sebagai standar . Itu esoteris. Dalam hal ini,%s
sebagaimana diberikanstrftime(3)
adalah "jumlah detik sejak zaman".Inilah cara saya melakukannya:
Sangat sederhana, ambil jumlah detik di awal, lalu ambil jumlah detik di akhir, dan cetak perbedaan dalam menit: detik.
sumber
awk
dalam kasus ini, karena Bash menangani bilangan aritmatika sama baiknya.awk
perintah untuk bash (jika tidak untuk yang lain, karena awk bekerja di shell lain). Saya lebih menyukai solusi ini. Tapi itu pendapat pribadi saya.Pilihan lain adalah menggunakan
datediff
daridateutils
( http://www.fresse.org/dateutils/#datediff ):Anda juga bisa menggunakannya
gawk
.mawk
1.3.4 juga memilikistrftime
danmktime
tetapi versi yang lebih lamamawk
dannawk
tidak.Atau inilah cara lain untuk melakukannya dengan GNU
date
:sumber
date
metode GNU Anda . Jenius.dateutils
melalui apt, tidak adadatediff
perintah - harus digunakandateutils.ddiff
.Saya ingin mengusulkan cara lain yang menghindari mengingat
date
perintah. Mungkin bermanfaat jika Anda telah mengumpulkan cap waktu dalam%T
format tanggal:kita bahkan dapat menangani milidetik dengan cara yang sama.
sumber
echo $(((60*60*$((10#$h)))+(60*$((10#$m)))+$((10#$s))))
bekerja untuk saya sejak saya dapatkanvalue too great for base (error token is "08")
Inilah beberapa keajaiban:
sed
mengganti a:
dengan formula untuk dikonversi ke 1/60. Kemudian perhitungan waktu yang dilakukan olehbc
sumber
Sampai saat ini (GNU coreutils) 7.4 Anda sekarang dapat menggunakan -d untuk melakukan aritmatika:
Unit yang dapat Anda gunakan adalah hari, tahun, bulan, jam, menit, dan detik:
sumber
Sebagai lanjutan dari jawaban Daniel Kamil Kozar, untuk menunjukkan jam / menit / detik:
Jadi skrip lengkapnya adalah:
sumber
Atau bungkus sedikit
Maka ini bekerja.
sumber
Berikut adalah solusi hanya menggunakan
date
kemampuan perintah menggunakan "lalu", dan tidak menggunakan variabel kedua untuk menyimpan waktu selesai:ini memberi:
sumber
sumber
date
.date
dapat memberi Anda perbedaan dan memformatnya untuk Anda (opsi OS X ditampilkan)Beberapa pemrosesan string dapat menghapus nilai-nilai kosong itu
Ini tidak akan berfungsi jika Anda menempatkan waktu lebih dulu. Jika Anda perlu mengatasinya, ubah
$(($(date ...) - $(date ...)))
ke$(echo $(date ...) - $(date ...) | bc | tr -d -)
sumber
Saya membutuhkan skrip perbedaan waktu untuk digunakan dengan
mencoder
(--endpos
relatif), dan solusi saya adalah memanggil skrip Python:fraksi detik juga didukung:
dan dapat memberitahu Anda bahwa perbedaan antara 200 dan 120 adalah 1j 20m:
dan dapat mengubah jumlah (mungkin pecahan) detik atau menit atau jam menjadi jj: mm: dd
timediff.py:
sumber
Dengan GNU
units
:sumber
Generalisasi solusi @ nisetama menggunakan tanggal GNU (Ubuntu 14.04 LTS) yang dapat dipercaya:
menghasilkan:
sumber
sumber
Tentukan fungsi ini (katakan dalam ~ / .bashrc):
Sekarang Anda dapat mengukur waktu bagian dari skrip Anda:
sangat berguna untuk menemukan bottlenecks eksekusi.
sumber
Saya menyadari ini adalah posting yang lebih tua, tetapi saya menemukan hari ini ketika mengerjakan sebuah skrip yang akan mengambil tanggal dan waktu dari file log dan menghitung delta. Script di bawah ini pasti berlebihan, dan saya sangat merekomendasikan memeriksa logika dan matematika saya.
Anda akan mendapatkan output sebagai berikut.
Saya memodifikasi skrip sedikit untuk membuatnya mandiri (mis. Hanya mengatur nilai variabel), tapi mungkin ide umum juga muncul. Anda mungkin ingin beberapa kesalahan tambahan memeriksa nilai negatif.
sumber
Saya tidak dapat mengomentari jawaban mcaleaa, maka saya memposting ini di sini. Variabel "diff" harus dalam huruf kecil. Berikut ini sebuah contoh.
Variabel sebelumnya dinyatakan dalam huruf kecil. Inilah yang terjadi ketika huruf besar digunakan.
Jadi, perbaikan cepat akan seperti ini
sumber
Inilah implementasi bash saya (dengan bit diambil dari SO lainnya ;-)
Tidak diuji, mungkin bermasalah.
sumber