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


31

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

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


您能提供一个例子/几个例子吗?
gabe。

1
您是说自纪元以来就有间隔或日期吗?
Paul Tomblin

Answers:


41

您可以使用如下形式:

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
}

例子:

$ displaytime 11617
3 hours 13 minutes and 37 seconds
$ displaytime 42
42 seconds
$ displaytime 666
11 minutes and 6 seconds

11

最简单,最干净的方法是使用这种衬板(此处假定为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')"

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


如果你的时间永远是不到一天的时间,你可以使用+%T格式小时:分钟:秒这date +%T "1970-01-01 + ${seconds} seconds"21:33:09
Yzmir拉米雷斯

7

归功于StéphaneGimenez,但如果某人只想在时间段小于一分钟时才显示秒,这是我使用的修改后的版本(也具有固定的复数形式):

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
}

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以获取漂亮的输出。
flickerfly

3

我会这样:

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

这是上面的一根衬里,已经分解好了,这样更容易理解:

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

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


2

我修改了上面的displaytime函数...如下:

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
}

因为我总是想看HH:MM:SS,即使它们是零。


1

我以atti的答案为基础,我很喜欢这个想法。

您可以使用bash内置的bash来执行此操作,printf该操作将自纪元以来的秒数作为参数。无需分叉即可运行date

您必须将时区设置为UTC,printf因为它会格式化本地时区中的时间,如果您不在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

在我的当地时间(当前为NZDT-+1300)中,如果我未设置时区,答案是错误的

$ seconds=123456789
$ printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1428 days 09 hours 33 minutes 09 seconds

有和没有设置时区

$ 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

请注意,bash 从bash-4.2-alpha开始printf引入了该%(datefmt)T符号。
主教

-1

这里一个

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

输出:

4d 9h:7m:24s

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.