Menampilkan detik sebagai hari / jam / menit / detik?


31

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 ...


Bisakah Anda memberikan contoh / beberapa contoh?
gabe.

1
Apakah Anda mengatakan Anda memiliki interval, atau tanggal sejak zaman?
Paul Tomblin

Jawaban:


41

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

11

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


Jika durasi Anda akan selalu kurang dari sehari, Anda dapat menggunakan +%Tformat untuk Jam: Menit: Detik untuk date +%T "1970-01-01 + ${seconds} seconds"mendapatkan ini21:33:09
Yzmir Ramirez

7

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'
}

Ini bekerja dengan sangat baik. Saya hanya menyisipkan fungsi ke skrip saya dan berlari convert $suntuk mendapatkan hasil yang cantik.
flickerfly

3

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 dateperintah di sub-perintah lain $(date -d ... ), untuk menghasilkan jam, menit, dan detik untuk jumlah detik tertentu.


2

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.


1

Saya membangun jawaban atti yang saya sukai sebagai ide.

Anda dapat melakukan ini dengan bash builtin printfyang akan mengambil detik sejak zaman sebagai argumen. Tidak perlu garpu untuk berlari date.

Anda harus mengatur zona waktu ke UTC untuk printfkarena 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

Perhatikan bahwa bash printfmemperkenalkan %(datefmt)Tnotasi ini dimulai dengan bash-4.2-alpha.
Uskup

-1

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

-2

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.


7
Itu kencan, bukan durasi, yang ditanyakan oleh pertanyaan itu.
Gilles 'SO- berhenti bersikap jahat'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.