![计算时间差(以毫秒为单位):](https://linux22.com/image/158632/%E8%AE%A1%E7%AE%97%E6%97%B6%E9%97%B4%E5%B7%AE%EF%BC%88%E4%BB%A5%E6%AF%AB%E7%A7%92%E4%B8%BA%E5%8D%95%E4%BD%8D%EF%BC%89%EF%BC%9A.png)
输入和输出错误:
14:00:11,320 14:00:11,453
**Correct Output** : Time difference is 133 milli seconds.
14:00:13,097 14:00:13,124
**Output in Error** : line 4: 124000000 - 097000000: value too great for base (error token is "097000000")
14:00:11:693 14:00:13:048
**Output in Error** : line 4: 048000000: value too great for base (error token is "048000000")
使用的脚本:
g=$(( $(date -d $b +%s) - $(date -d $a +%s) ))
h=$(( $(date -d $b +%N) - $(date -d $a +%N) ))
k=$(( (g * 1000) + (h / 1000000) ))
printf "Total time difference: %i milli seconds\n" $k
答案1
你是对的,这个数学在 bash 和大多数其他 shell 下失败了,因为它们遵循 C 约定,其中以 开头的数字0
是八进制,不是十进制:
$ echo "$((124000000 - 097000000))"
bash: 124000000 - 097000000: value too great for base (error token is "097000000")
一种解决方案是正确识别要 bash 的数字为基数 10:
$ echo "$((10#124000000 - 10#097000000))"
27000000
问题是,如果没有10#
前缀,bash 会假定以零开头的数字是八进制。
或者,使用bc
:
$ echo "124000000 - 097000000" | bc -l
27000000
或者使用 awk:
$ echo "124000000 097000000" | awk '{print $1-$2}'
27000000
结合数学和 printf:
$ g=124000000
$ h=097000000
$ printf "Total time difference: %i milli seconds\n" "$(echo "$g - $h" | bc -l )"
Total time difference: 27000000 milli seconds
或者,
$ g=124000000
$ h=097000000
$ echo "$g $h" | awk '{printf "Total time difference: %i milliseconds\n",$1-$2}'; )
Total time difference: 27000000 milli seconds
文档
从man bash
:
以 0 开头的常量被解释为八进制数。前导 0x 或 0X 表示十六进制。否则,数字采用 [base#]n 形式,其中可选基数是表示算术基数的 2 到 64 之间的十进制数,n 是该基数中的数字。
结合数学和日期
$ echo "$(( $(date -d '14:00:13.124' '+10#%s%N') - $(date -d '14:00:13.097' '+10#%s%N') ))"
27000000
如果我们想从纳秒转换为毫秒:
$ echo "$(( ($(date -d '14:00:13.124' '+10#%s%N') - $(date -d '14:00:13.097' '+10#%s%N'))/1000000 ))"
27
$ echo "$(( ($(date -d '14:00:05.320' '+10#%s%N') - $(date -d '14:00:04.909' '+10#%s%N'))/1000000 ))"
411