我正在尝试将这个时间格式的21410.912099转换成这个12d 1h 14m 17.912 s
我试过使用这样的脚本,但是它不起作用(不能解析一个点) :(
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' 
}发布于 2021-12-20 10:28:45
使用.作为分隔符将值拆分为数组。
使用Bash内置的printf将秒重新格式化为自时代以来的间隔。
$ Input=1721410.912099
$ IFS='.' s_ms=( ${Input} )
$ declare -p s_ms
declare -a s_ms=([0]="1721410" [1]="912099")
$ printf -v Out '%(%-dd %-Hh %-Mm %-S)T.%s s' "${s_ms[0]}" "${s_ms[1]:0:3}"
$ declare -p Out
declare -- Out="20d 23h 10m 10.912 s"编辑:对不起,这至少有三种方式是错误的。我用3707.001234测试了它。
(1)由于基数为1970-01-01,因此在白天有一个一次性错误。
(2)它在小时内有一个一次性的错误,我无法立即看到(我在格林尼治时间,但明显的怀疑是时区)。date -d @0也报道了Thu  1 Jan 01:00:00 BST 1970。英国夏季时间在一月?
(3) 2678400以上的间隔时间将缩短整个月。
棘手的事情,这些约会。我很抱歉。但是如何处理秒的分数是正确的--解析它并对它进行子字符串。
谷歌补充: BST与英国实验
全年英国夏季时间(BST)于1968年2月至1971年10月生效.
发布于 2021-12-20 13:35:42
关于时间的小数部分,您可以使用${var##prefix}和${var%%suffix}展开来拆分值。它们从$var值中删除最长的匹配前缀和后缀。
因此,在添加注释的这两行中:
converts() {
    t=$1
    case $t in
        *.*) tfrac=${t##*.}       # fractional seconds
             t=${t%%.*}           # full seconds
             ;;
          *) tfrac=0              # no decimal point
             ;;
    esac
    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' 
}我们得到了。
$ converts $(( 1*86400 + 23*3600 + 45*60 + 6))
1 day 23 hours 45 minutes 在尝试删除部分小数点之前,我们需要检查输入是否有小数点,因为如果没有点,${t##*.}只返回$t。
我将由您决定在哪里使用tfrac。也许就像
printf "%d.%s seconds" $s $tfrac(不要使用%d.%d,它会移除前导零,例如123.05会变成123.5)
或者,在12d 1h 14m 17.912s格式中:
converts() {
    t=$1
    case $t in
        *.*) tfrac=${t##*.}       # fractional seconds
             t=${t%%.*}           # full seconds
             ;;
          *) tfrac=0              # no decimal point
             ;;
    esac
    d=$((t/60/60/24))
    h=$((t/60/60%24))
    m=$((t/60%60))
    s=$((t%60))
    printf "%dd %dh %dm %d.%ss\n" "$d" "$h" "$m" "$s" "$tfrac"
}和
$ converts  $(( 1*86400 + 23*3600 + 45*60 + 6)).987
1d 23h 45m 6.987shttps://unix.stackexchange.com/questions/683143
复制相似问题