Apakah mungkin untuk dengan mudah memformat detik sebagai waktu yang dapat dibaca manusia di bash?
Saya tidak ingin memformatnya sebagai tanggal, tetapi sebagai jumlah hari / jam / menit, dll ...
Apakah mungkin untuk dengan mudah memformat detik sebagai waktu yang dapat dibaca manusia di bash?
Saya tidak ingin memformatnya sebagai tanggal, tetapi sebagai jumlah hari / jam / menit, dll ...
Jawaban:
Anda dapat menggunakan sesuatu seperti ini:
function displaytime {
local T=$1
local D=$((T/60/60/24))
local H=$((T/60/60%24))
local M=$((T/60%60))
local S=$((T%60))
(( $D > 0 )) && printf '%d days ' $D
(( $H > 0 )) && printf '%d hours ' $H
(( $M > 0 )) && printf '%d minutes ' $M
(( $D > 0 || $H > 0 || $M > 0 )) && printf 'and '
printf '%d seconds\n' $S
}
Contoh:
$ displaytime 11617
3 hours 13 minutes and 37 seconds
$ displaytime 42
42 seconds
$ displaytime 666
11 minutes and 6 seconds
Cara termudah dan terbersih adalah liner satu ini (dengan asumsi GNU date
):
Jika jumlah detiknya, katakan:
seconds=123456789 # as in one of the answers above
eval "echo $(date -ud "@$seconds" +'$((%s/3600/24)) days %H hours %M minutes %S seconds')"
-> output: 1428 days 21 hours 33 minutes 09 seconds
+%T
format untuk Jam: Menit: Detik untuk date +%T "1970-01-01 + ${seconds} seconds"
mendapatkan ini21:33:09
Kredit jatuh ke Stéphane Gimenez tetapi jika seseorang ingin menampilkan detik hanya jika suatu periode kurang dari satu menit di sini adalah versi modifikasi saya yang saya gunakan (juga dengan pluralisasi tetap):
converts()
{
local t=$1
local d=$((t/60/60/24))
local h=$((t/60/60%24))
local m=$((t/60%60))
local s=$((t%60))
if [[ $d > 0 ]]; then
[[ $d = 1 ]] && echo -n "$d day " || echo -n "$d days "
fi
if [[ $h > 0 ]]; then
[[ $h = 1 ]] && echo -n "$h hour " || echo -n "$h hours "
fi
if [[ $m > 0 ]]; then
[[ $m = 1 ]] && echo -n "$m minute " || echo -n "$m minutes "
fi
if [[ $d = 0 && $h = 0 && $m = 0 ]]; then
[[ $s = 1 ]] && echo -n "$s second" || echo -n "$s seconds"
fi
echo
}
Contoh alternatif dalam POSIX:
converts(){
t=$1
d=$((t/60/60/24))
h=$((t/60/60%24))
m=$((t/60%60))
s=$((t%60))
if [ $d -gt 0 ]; then
[ $d = 1 ] && printf "%d day " $d || printf "%d days " $d
fi
if [ $h -gt 0 ]; then
[ $h = 1 ] && printf "%d hour " $h || printf "%d hours " $h
fi
if [ $m -gt 0 ]; then
[ $m = 1 ] && printf "%d minute " $m || printf "%d minutes " $m
fi
if [ $d = 0 ] && [ $h = 0 ] && [ $m = 0 ]; then
[ $s = 1 ] && printf "%d second" $s || printf "%d seconds" $s
fi
printf '\n'
}
convert $s
untuk mendapatkan hasil yang cantik.
Saya akan melakukannya seperti ini:
$ seconds=123456789; echo $((seconds/86400))" days "$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
1428 days 21 hours 33 minutes 09 seconds
$
Inilah satu liner di atas, yang dipecah sehingga lebih mudah dipahami:
$ seconds=123456789
$ echo $((seconds/86400))" days"\
$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
Dalam contoh di atas, saya menampilkan output dari perintah lain yang dijalankan di dalam $( ... )
sub-perintah. Sub-perintah itu melakukan ini, menghitung jumlah hari (detik / 86400), kemudian menggunakan date
perintah di sub-perintah lain $(date -d ... )
, untuk menghasilkan jam, menit, dan detik untuk jumlah detik tertentu.
Saya mengubah fungsi tampilan di atas ... sebagai berikut:
seconds2time ()
{
T=$1
D=$((T/60/60/24))
H=$((T/60/60%24))
M=$((T/60%60))
S=$((T%60))
if [[ ${D} != 0 ]]
then
printf '%d days %02d:%02d:%02d' $D $H $M $S
else
printf '%02d:%02d:%02d' $H $M $S
fi
}
karena saya selalu ingin melihat HH: MM: SS, bahkan jika mereka nol.
Saya membangun jawaban atti yang saya sukai sebagai ide.
Anda dapat melakukan ini dengan bash builtin printf
yang akan mengambil detik sejak zaman sebagai argumen. Tidak perlu garpu untuk berlari date
.
Anda harus mengatur zona waktu ke UTC untuk printf
karena format waktu di zona waktu lokal Anda dan Anda akan mendapatkan jawaban yang salah jika Anda tidak berada dalam waktu UTC.
$ seconds=123456789
$ TZ=UTC printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1428 days 21 hours 33 minutes 09 seconds
Di waktu lokal saya (yang saat ini NZDT - +1300) jawabannya salah jika saya tidak mengatur zona waktu
$ seconds=123456789
$ printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1428 days 09 hours 33 minutes 09 seconds
Dengan dan tanpa mengatur zona waktu
$ seconds=$(( 3600 * 25))
$ printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1 days 13 hours 00 minutes 00 seconds
$ TZ=UTC printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1 days 01 hours 00 minutes 00 seconds
printf
memperkenalkan %(datefmt)T
notasi ini dimulai dengan bash-4.2-alpha.
Di sini satu
secs=378444
echo $(($secs/86400))d $(($(($secs - $secs/86400*86400))/3600))h:$(($(($secs - $secs/86400*86400))%3600/60))m:$(($(($secs - $secs/86400*86400))%60))s
Keluaran:
4d 9h:7m:24s
date --date '@1005454800'
memberi Anda Sun Nov 11 00:00:00 EST 2001
, yaitu 1005454800 detik setelah zaman Unix. Anda dapat memformatnya dengan opsi tanggal + FORMAT.