Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Is it possible to easily format seconds as a human-readable time in bash?

I don't want to format it as a date, but as the number of days/hours/minutes, etc...

share|improve this question
    
Could you provide an example/several examples please? –  gabe. Dec 16 '11 at 22:51
1  
Are you saying you have an interval, or a date since the epoch? –  Paul Tomblin Dec 16 '11 at 23:22

5 Answers 5

up vote 16 down vote accepted

You can use something like this:

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
}

Examples:

$ displaytime 11617
3 hours 13 minutes and 37 seconds
$ displaytime 42
42 seconds
$ displaytime 666
11 minutes and 6 seconds
share|improve this answer

I'd do it like this:

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

Here's the one liner above, broken down so that it's easier to understand:

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

In the above I'm echoing out the output of another command that's run inside the $( ... ) sub-command. That sub-command is doing this, calculating the number of days (seconds/86400), then using the date command in another sub-command $(date -d ... ), to generate the hours, minutes, and seconds for a given number of seconds.

share|improve this answer
    
@slm: thank you for your edits –  atti Jul 24 at 15:06

I modified the displaytime function above... as follows:

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
}

because I always want to see HH:MM:SS, even if they are zeros.

share|improve this answer

Credit goes to Stéphane Gimenez but if someone would like to display seconds only if a period is less than a minute here is my modified version that I use (also with fixed pluralization):

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
}
share|improve this answer

date --date '@1005454800' gives you Sun Nov 11 00:00:00 EST 2001, which is 1005454800 seconds after the Unix epoch. You can format that with the date +FORMAT option.

share|improve this answer
3  
That's a date, not a duration, which the question was asking about. –  Gilles Dec 17 '11 at 23:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.