我使用日期+“%T”打印开始和结束时间,结果如下:

10:33:56
10:36:10

我如何计算并打印这两者之间的差值呢?

我想要的是:

2m 14s

当前回答

使用GNU日期(可靠的Ubuntu 14.04 LTS)概括@nisetama的解决方案:

start=`date`
# <processing code>
stop=`date`
duration=`date -ud@$(($(date -ud"$stop" +%s)-$(date -ud"$start" +%s))) +%T`

echo $start
echo $stop
echo $duration

收益率:

Wed Feb 7 12:31:16 CST 2018
Wed Feb 7 12:32:25 CST 2018
00:01:09

其他回答

Bash有一个方便的SECONDS内建变量,用于跟踪自shell启动以来已经过的秒数。此变量在赋值时保留其属性,赋值后返回的值为自赋值后的秒数加上赋值。

因此,您可以在启动计时事件之前将SECONDS设置为0,在事件发生后读取SECONDS,并在显示之前进行时间算术。

#!/usr/bin/env bash

SECONDS=0
# do some work
duration=$SECONDS
echo "$(($duration / 60)) minutes and $(($duration % 60)) seconds elapsed."

由于这个解决方案不依赖于date +%s(这是一个GNU扩展),所以它可以移植到Bash支持的所有系统。

如果你已经计算出了时间差值,并且它们小于1天,这里有一个非常边缘的BC用例,可以将输出格式化为

HH MM SS.xxxx

24小时格式,请记住小数点右边的数字是以60为基数打印的

Jot -w 'obase = 60;%。3f' - 1.3219567 300 73.6543211 | BC

       01.19 19
    01 14.58 33
    02 28.37 51
    03 42.17 06  # 3 mins 42 secs 
    04 55.56 20  
          ...
          ...
 19 38 10.54 32  # 19 hrs 38 mins 10 secs 
                 #
                 # (or 7:38pm, if it's representing absolute time)

但这绝对是一个快速得到大致数字的方法

日期可以给你的差异和格式为您(OS X选项显示)

date -ujf%s $(($(date -jf%T "10:36:10" +%s) - $(date -jf%T "10:33:56" +%s))) +%T
# 00:02:14

date -ujf%s $(($(date -jf%T "10:36:10" +%s) - $(date -jf%T "10:33:56" +%s))) \
    +'%-Hh %-Mm %-Ss'
# 0h 2m 14s

某些字符串处理可以删除这些空值

date -ujf%s $(($(date -jf%T "10:36:10" +%s) - $(date -jf%T "10:33:56" +%s))) \
    +'%-Hh %-Mm %-Ss' | sed "s/[[:<:]]0[hms] *//g"
# 2m 14s

如果你把较早的时间放在前面,这是行不通的。如果你需要处理,改变$(($(日期 ...) - $( 日期……)))(echo $(美元日期 ...) - $( 公元前日期…)| | tr - d -)

以下是我的做法:

START=$(date +%s);
sleep 1; # Your stuff
END=$(date +%s);
echo $((END-START)) | awk '{print int($1/60)":"int($1%60)}'

非常简单,取开始时的秒数,然后取结束时的秒数,打印出以分钟为单位的差值:秒。

我想提出另一种避免召回日期命令的方法。如果你已经收集了%T日期格式的时间戳,这可能会有帮助:

ts_get_sec()
{
  read -r h m s <<< $(echo $1 | tr ':' ' ' )
  echo $(((h*60*60)+(m*60)+s))
}

start_ts=10:33:56
stop_ts=10:36:10

START=$(ts_get_sec $start_ts)
STOP=$(ts_get_sec $stop_ts)
DIFF=$((STOP-START))

echo "$((DIFF/60))m $((DIFF%60))s"

我们甚至可以用同样的方法处理毫秒。

ts_get_msec()
{
  read -r h m s ms <<< $(echo $1 | tr '.:' ' ' )
  echo $(((h*60*60*1000)+(m*60*1000)+(s*1000)+ms))
}

start_ts=10:33:56.104
stop_ts=10:36:10.102

START=$(ts_get_msec $start_ts)
STOP=$(ts_get_msec $stop_ts)
DIFF=$((STOP-START))

min=$((DIFF/(60*1000)))
sec=$(((DIFF%(60*1000))/1000))
ms=$(((DIFF%(60*1000))%1000))

echo "${min}:${sec}.$ms"