Exibindo segundos como dias / horas / minutos / segundos?

25

É possível formatar facilmente segundos como um tempo legível em humanos no bash?

Eu não quero formatá-lo como uma data, mas como o número de dias / horas / minutos, etc ...

    
por Tyilo 16.12.2011 / 23:29

7 respostas

37

Você pode usar algo assim:

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
}

Exemplos:

$ displaytime 11617
3 hours 13 minutes and 37 seconds
$ displaytime 42
42 seconds
$ displaytime 666
11 minutes and 6 seconds
    
por 17.12.2011 / 00:04
10

A maneira mais fácil e mais limpa é esse liner (aqui assumindo o GNU date ):

Se o número de segundos for, digamos:

seconds=123456789 # as in one of the answers above

eval "echo $(date -ud "@$seconds" +'$((%s/3600/24)) days %H hours %M minutes %S seconds')"

- > saída: 1428 days 21 hours 33 minutes 09 seconds

    
por 20.01.2017 / 11:18
5

O crédito vai para Stéphane Gimenez mas se alguém quiser exibir segundos apenas se um período for menor que um minuto, aqui está minha versão modificada que uso (também com pluralização fixa):

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
}

Um exemplo alternativo no 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'
}
    
por 27.11.2014 / 15:57
3

Eu faria assim:

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

Aqui está o único folheto acima, dividido para que seja mais fácil de entender:

$ seconds=123456789
$ echo $((seconds/86400))" days"\
     $(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")

No exemplo acima, estou ecoando a saída de outro comando executado dentro do subcomando $( ... ) . Esse subcomando está fazendo isso, calculando o número de dias (segundos / 86400) e, em seguida, usando o comando date em outro subcomando $(date -d ... ) , para gerar as horas, minutos e segundos para um determinado número de segundos .

    
por 22.07.2015 / 14:30
1

Eu modifiquei a função de tempo de exibição acima ... como segue:

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
}

porque eu sempre quero ver HH: MM: SS, mesmo que sejam zeros.

    
por 20.12.2014 / 02:01
-1

date --date '@1005454800' fornece Sun Nov 11 00:00:00 EST 2001 , que é 1005454800 segundos após a época do Unix. Você pode formatar isso com a opção data + FORMATO.

    
por 17.12.2011 / 00:19
-1

Aqui um

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

Saída:

4d 9h:7m:24s
    
por 27.06.2018 / 10:30

Tags