将秒显示为天/小时/分钟/秒?

Tyi*_*ilo 42 bash

是否可以在 bash 中轻松地将秒格式化为人类可读的时间?

我不想将其格式化为日期,而是将其格式化为天/小时/分钟等...

Sté*_*nez 55

你可以使用这样的东西:

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
}
Run Code Online (Sandbox Code Playgroud)

例子:

$ displaytime 11617
3 hours 13 minutes and 37 seconds
$ displaytime 42
42 seconds
$ displaytime 666
11 minutes and 6 seconds
Run Code Online (Sandbox Code Playgroud)

  • 这真的很好——唯一缺少的是去掉单日、小时、分钟和秒中的 -s。 (2认同)

Jac*_*ues 24

最简单和最干净的方法是这个 liner (这里假设 GNU date):

如果秒数是,说:

seconds=123456789 # as in one of the answers above

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

--> 输出: 1428 days 21 hours 33 minutes 09 seconds

  • 如果您的持续时间始终小于一天,您可以使用“+%T”格式表示此“日期 +%T "1970-01-01 + ${seconds} 秒”的小时:分钟:秒,以获得“21” :33:09` (3认同)

小智 8

幸得斯特凡希门尼斯,但如果有人想只有一段小于显示秒,不到一分钟,这里是我修改后的版本,我使用的(也有固定的复数):

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
}
Run Code Online (Sandbox Code Playgroud)

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'
}
Run Code Online (Sandbox Code Playgroud)


小智 6

我会这样做:

$ 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
$
Run Code Online (Sandbox Code Playgroud)

这是上面的一行,进行了细分,以便更容易理解:

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

$( ... )在上面,我回显了在子命令内运行的另一个命令的输出。该子命令正在执行此操作,计算天数(秒/86400),然后使用date另一个子命令中的命令$(date -d ... )来生成给定秒数的小时、分钟和秒。