将秒数转换为小时,分钟,秒

Cha*_*lie 41 bash

如何将秒数转换为小时,分钟和秒?

show_time() {
  ?????
}

show_time 36 # 00:00:36
show_time 1036 # 00:17:26
show_time 91925 # 25:32:05
Run Code Online (Sandbox Code Playgroud)

per*_*eal 74

#!/bin/sh

convertsecs() {
 ((h=${1}/3600))
 ((m=(${1}%3600)/60))
 ((s=${1}%60))
 printf "%02d:%02d:%02d\n" $h $m $s
}
TIME1="36"
TIME2="1036"
TIME3="91925"

echo $(convertsecs $TIME1)
echo $(convertsecs $TIME2)
echo $(convertsecs $TIME3)
Run Code Online (Sandbox Code Playgroud)

浮动秒:

convertsecs() {
 h=$(bc <<< "${1}/3600")
 m=$(bc <<< "(${1}%3600)/60")
 s=$(bc <<< "${1}%60")
 printf "%02d:%02d:%05.2f\n" $h $m $s
}
Run Code Online (Sandbox Code Playgroud)


ACy*_*lic 47

使用日期,转换为UTC:

$ date -d@36 -u +%H:%M:%S
00:00:36
$ date -d@1036 -u +%H:%M:%S
00:17:16
$ date -d@12345 -u +%H:%M:%S
03:25:45
Run Code Online (Sandbox Code Playgroud)

限制是小时将在23处循环,但这对于您想要单行的大多数用例无关紧要.

在macOS上,运行brew install coreutils并替换dategdate

  • OP 要求 bash,所以我假设 GNU 日期 (3认同)
  • 我赞成你的回答,因为它对我很有帮助,但我正在使用 GNU/Linux。假设任何使用 bash 的人都在使用 GNU/Linux(和 GNU date)是不安全的。我首先想到的是 OSX,但我认为 BSD 也属于这一类。 (3认同)
  • 我认为这只是GNU的“日期”,而不是可移植的。 (2认同)
  • MacOS 上不需要 `coreutils`,您可以使用 ootb `date`:/sf/answers/4685029891/ (2认同)

小智 43

我所知道的最简单的方法:

secs=100000
printf '%dh:%dm:%ds\n' $(($secs/3600)) $(($secs%3600/60)) $(($secs%60))
Run Code Online (Sandbox Code Playgroud)

注意 - 如果你想要几天,那么只需添加其他单位并除以86400.

  • 这不会给你领先的`0`s:使用`%02d`而不是'%d`. (6认同)
  • 如果你想要几天,你还需要更改小时,这样它们就不会超过 24: `printf '%dd %dh:%dm:%ds\n' $(($secs/86400)) $(($secs%86400 /3600)) $(($secs%3600/60)) $(($secs%60))` (2认同)

cho*_*oba 30

我自己使用以下功能:

function show_time () {
    num=$1
    min=0
    hour=0
    day=0
    if((num>59));then
        ((sec=num%60))
        ((num=num/60))
        if((num>59));then
            ((min=num%60))
            ((num=num/60))
            if((num>23));then
                ((hour=num%24))
                ((day=num/24))
            else
                ((hour=num))
            fi
        else
            ((min=num))
        fi
    else
        ((sec=num))
    fi
    echo "$day"d "$hour"h "$min"m "$sec"s
}
Run Code Online (Sandbox Code Playgroud)

注意它也算几天.此外,它显示您的上一个号码的不同结果.


qub*_*dup 28

简单的单线程

$ secs=236521
$ printf '%dh:%dm:%ds\n' $(($secs/3600)) $(($secs%3600/60)) $(($secs%60))
65h:42m:1s
Run Code Online (Sandbox Code Playgroud)

带有前导零

$ secs=236521
$ printf '%02dh:%02dm:%02ds\n' $(($secs/3600)) $(($secs%3600/60)) $(($secs%60))
65h:42m:01s
Run Code Online (Sandbox Code Playgroud)

随着天

$ secs=236521
$ printf '%dd:%dh:%dm:%ds\n' $(($secs/86400)) $(($secs%86400/3600)) $(($secs%3600/60)) \
  $(($secs%60))
2d:17h:42m:1s
Run Code Online (Sandbox Code Playgroud)

有纳秒

$ secs=21218.6474912
$ printf '%02dh:%02dm:%02fs\n' $(echo -e "$secs/3600\n$secs%3600/60\n$secs%60"| bc | xargs echo)
05h:53m:38.647491s
Run Code Online (Sandbox Code Playgroud)

基于/sf/answers/1991596561/但编辑被拒绝.


eMP*_*584 11

对于我们懒惰的人:现成的脚本可在https://github.com/k0smik0/FaCRI/blob/master/fbcmd/bin/displaytime获得:

#!/bin/bash

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

基本上只是另一个解决方案的另一个旋转,但有额外的奖励抑制空时间单位(fe 10 seconds而不是0 hours 0 minutes 10 seconds).无法完全跟踪函数的原始来源,发生在多个git repos中.


Sco*_*lby 8

使用dc

$ echo '12345.678' | dc -e '?1~r60~r60~r[[0]P]szn[:]ndZ2>zn[:]ndZ2>zn[[.]n]sad0=ap'
3:25:45.678
Run Code Online (Sandbox Code Playgroud)

该表达式?1~r60~r60~rn[:]nn[:]nn[[.]n]sad0=ap执行以下操作:

?   read a line from stdin
1   push one
~   pop two values, divide, push the quotient followed by the remainder
r   reverse the top two values on the stack
60  push sixty
~   pop two values, divide, push the quotient followed by the remainder
r   reverse the top two values on the stack
60  push sixty
~   pop two values, divide, push the quotient followed by the remainder
r   reverse the top two values on the stack
[   interpret everything until the closing ] as a string
  [0]   push the literal string '0' to the stack
  n     pop the top value from the stack and print it with no newline
]   end of string, push the whole thing to the stack
sz  pop the top value (the string above) and store it in register z
n   pop the top value from the stack and print it with no newline
[:] push the literal string ':' to the stack
n   pop the top value from the stack and print it with no newline
d   duplicate the top value on the stack
Z   pop the top value from the stack and push the number of digits it has
2   push two
>z  pop the top two values and executes register z if the original top-of-stack is greater
n   pop the top value from the stack and print it with no newline
[:] push the literal string ':' to the stack
n   pop the top value from the stack and print it with no newline
d   duplicate the top value on the stack
Z   pop the top value from the stack and push the number of digits it has
2   push two
>z  pop the top two values and executes register z if the original top-of-stack is greater
n   pop the top value from the stack and print it with no newline
[   interpret everything until the closing ] as a string
  [.]   push the literal string '.' to the stack
  n     pop the top value from the stack and print it with no newline
]   end of string, push the whole thing to the stack
sa  pop the top value (the string above) and store it in register a
d   duplicate the top value on the stack
0   push zero
=a  pop two values and execute register a if they are equal
p   pop the top value and print it with a newline
Run Code Online (Sandbox Code Playgroud)

每次操作后堆栈状态的示例执行:

    : <empty stack>
?   : 12345.678
1   : 1, 12345.678
~   : .678, 12345
r   : 12345, .678  # stack is now seconds, fractional seconds
60  : 60, 12345, .678
~   : 45, 205, .678
r   : 205, 45, .678  # stack is now minutes, seconds, fractional seconds
60  : 60, 205, 45, .678
~   : 25, 3, 45, .678
r   : 3, 25, 45, .678  # stack is now hours, minutes, seconds, fractional seconds

[[0]n]  : [0]n, 3, 25, 45, .678
sz  : 3, 25, 45, .678  # '[0]n' stored in register z

n   : 25, 45, .678  # accumulated stdout: '3'
[:] : :, 25, 45, .678
n   : 25, 45, .678  # accumulated stdout: '3:'
d   : 25, 25, 45, .678
Z   : 2, 25, 45, .678
2   : 2, 2, 25, 45, .678
>z  : 25, 45, .678  # not greater, so register z is not executed
n   : 45, .678  # accumulated stdout: '3:25'
[:] : :, 45, .678
n   : 45, .678  # accumulated stdout: '3:25:'
d   : 45, 45, .678
Z   : 2, 45, 45, .678
2   : 2, 2, 45, .678
>z  : 45, .678  # not greater, so register z is not executed
n   : .678  # accumulated stdout: '3:25:45'

[[.]n]  : [.]n, .678
sa  : .678  # '[.]n' stored to register a
d   : .678, .678
0   : 0, .678, .678
=a  : .678  # not equal, so register a not executed
p   : <empty stack>  # accumulated stdout: '3:25:45.678\n'
Run Code Online (Sandbox Code Playgroud)

在 0 小数秒的情况下:

    : 3, 25, 45, 0  # starting just before we begin to print

n   : 25, 45, .678  # accumulated stdout: '3'
[:] : :, 25, 45, .678
n   : 25, 45, .678  # accumulated stdout: '3:'
d   : 25, 25, 45, .678
Z   : 2, 25, 45, .678
2   : 2, 2, 25, 45, .678
>z  : 25, 45, .678  # not greater, so register z is not executed
n   : 45, .678  # accumulated stdout: '3:25'
[:] : :, 45, .678
n   : 45, .678  # accumulated stdout: '3:25:'
d   : 45, 45, .678
Z   : 2, 45, 45, .678
2   : 2, 2, 45, .678
>z  : 45, .678  # not greater, so register z is not executed
n   : .678  # accumulated stdout: '3:25:45'

[[.]n]  : [.]n, 0
sa  : 0  # '[.]n' stored to register a
d   : 0, 0
0   : 0, 0, 0
=a  : 0  # equal, so register a executed
  [.] : ., 0
  n   : 0  # accumulated stdout: '3:35:45.'
p   : <empty stack>  # accumulated stdout: '3:25:45.0\n'
Run Code Online (Sandbox Code Playgroud)

如果分钟值小于 10:

    : 3, 9, 45, 0  # starting just before we begin to print

n   : 9, 45, .678  # accumulated stdout: '3'
[:] : :, 9, 45, .678
n   : 9, 45, .678  # accumulated stdout: '3:'
d   : 9, 9, 45, .678
Z   : 1, 9, 45, .678
2   : 2, 1, 9, 45, .678
>z  : 9, 45, .678  # greater, so register z is executed
  [0]   : 0, 9, 45, .678
  n     : 9, 45, .678  # accumulated stdout: '3:0' 
n   : 9, .678  # accumulated stdout: '3:09'
# ...and continues as above
Run Code Online (Sandbox Code Playgroud)

编辑:这有一个错误,可以打印像 7:7:34.123 这样的字符串。如有必要,我已将其修改为打印前导零。

  • +1,当然是“本周不可维护代码奖”的有力候选人:-) 但说真的,感谢您提醒我们“dc”,非常强大。 (7认同)
  • 谢谢你!我觉得如果您将格式化交给另一个实用程序,总体来说会更简单,但我真的很欣赏 dc 在这里带来的东西,即。简洁的除法+余数运算,可以在不重复的情况下表达整体逻辑。不管怎样,我所说的放弃格式就是这样的:`echo 12345.678 | dc-e'?1~r 60~r 60~r f' | 粘贴 -s | awk '{printf "%02d:%02d:%02d%s\n", $1, $2, $3, $4}'` (2认同)

dtl*_*m26 8

直接通过awk

echo $SECONDS | awk '{printf "%d:%02d:%02d", $1/3600, ($1/60)%60, $1%60}'
Run Code Online (Sandbox Code Playgroud)


Vau*_*ter 5

以上所有都是针对bash的,不管那些"#!/ bin/sh"没有任何基础将是:

convertsecs() {
    h=`expr $1 / 3600`
    m=`expr $1  % 3600 / 60`
    s=`expr $1 % 60`
    printf "%02d:%02d:%02d\n" $h $m $s
}
Run Code Online (Sandbox Code Playgroud)


Lri*_*Lri 5

t=12345;printf %02d:%02d:%02d\\n $((t/3600)) $((t%3600/60)) $((t%60)) # POSIX
echo 12345|awk '{printf "%02d:%02d:%02d",$0/3600,$0%3600/60,$0%60}' # POSIX awk
date -d @12345 +%T # GNU date
date -r 12345 +%T # OS X's date
Run Code Online (Sandbox Code Playgroud)

如果其他人正在寻找如何做相反的事情:

IFS=: read h m s<<<03:25:45;echo $((h*3600+m*60+s)) # POSIX
echo 03:25:45|awk -F: '{print 3600*$1+60*$2+$3}' # POSIX awk
Run Code Online (Sandbox Code Playgroud)


ccp*_*zza 5

它是使用开箱即用的MacOS的,具体的答复/bin/date,并没有要求的GNU版本date

# convert 195 seconds to MM:SS format, i.e. 03:15
/bin/date -ju -f "%s" 195 "+%M:%S"

## OUTPUT: 03:15
Run Code Online (Sandbox Code Playgroud)

如果你也想有时间:

/bin/date -ju -f "%s" 3600 "+%H:%M:%S"
# OUTPUT: 01:00:00

Run Code Online (Sandbox Code Playgroud)

注意:如果你想处理小时,那么-u它是必需的,因为它强制使用 UTC 时间,没有它你会得到错误的输出,除非你住在 UTC 时区:

-u      Display or set the date in UTC (Coordinated Universal) time.
Run Code Online (Sandbox Code Playgroud)

有关为什么-u需要的解释,请参阅

  • 甚至更短:`date -ur 3600 +%T`。`-r` 告诉它以自纪元以​​来的秒数读取输入,而不设置系统数据(本质上相当于 `-j -f "%s"`),而 `%T` 格式是 `% 的缩写H:%M:%S`。这适用于 macOS 和至少 NetBSD,但不适用于 GNU 的“date”命令(即在 Linux 上),其中“-r”选项意味着完全不同的东西。 (3认同)