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

10:33:56
10:36:10

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

我想要的是:

2m 14s

当前回答

另一种选择是使用dateutils (http://www.fresse.org/dateutils/#datediff):)中的datediff

$ datediff 10:33:56 10:36:10
134s
$ datediff 10:33:56 10:36:10 -f%H:%M:%S
0:2:14
$ datediff 10:33:56 10:36:10 -f%0H:%0M:%0S
00:02:14

你也可以用gawk。Mawk 1.3.4也有strftime和mktime,但旧版本的Mawk和nawk没有。

$ TZ=UTC0 awk 'BEGIN{print strftime("%T",mktime("1970 1 1 10 36 10")-mktime("1970 1 1 10 33 56"))}'
00:02:14

或者这里有另一种GNU日期的方法:

$ date -ud@$(($(date -ud'1970-01-01 10:36:10' +%s)-$(date -ud'1970-01-01 10:33:56' +%s))) +%T
00:02:14

其他回答

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支持的所有系统。

这是我的bash实现(bit从其他SO;-)

function countTimeDiff() {
    timeA=$1 # 09:59:35
    timeB=$2 # 17:32:55

    # feeding variables by using read and splitting with IFS
    IFS=: read ah am as <<< "$timeA"
    IFS=: read bh bm bs <<< "$timeB"

    # Convert hours to minutes.
    # The 10# is there to avoid errors with leading zeros
    # by telling bash that we use base 10
    secondsA=$((10#$ah*60*60 + 10#$am*60 + 10#$as))
    secondsB=$((10#$bh*60*60 + 10#$bm*60 + 10#$bs))
    DIFF_SEC=$((secondsB - secondsA))
    echo "The difference is $DIFF_SEC seconds.";

    SEC=$(($DIFF_SEC%60))
    MIN=$((($DIFF_SEC-$SEC)%3600/60))
    HRS=$((($DIFF_SEC-$MIN*60)/3600))
    TIME_DIFF="$HRS:$MIN:$SEC";
    echo $TIME_DIFF;
}

$ countTimeDiff 2:15:55 2:55:16
The difference is 2361 seconds.
0:39:21

未测试,可能有bug。

截至目前(GNU coreutils) 7.4,你现在可以使用-d来做算术:

$ date -d -30days
Sat Jun 28 13:36:35 UTC 2014

$ date -d tomorrow
Tue Jul 29 13:40:55 UTC 2014

你可以使用的单位是天、年、月、小时、分钟和秒:

$ date -d tomorrow+2days-10minutes
Thu Jul 31 13:33:02 UTC 2014

下面是一个只使用日期命令功能的解决方案,使用“ago”,而不使用第二个变量来存储完成时间:

#!/bin/bash

# save the current time
start_time=$( date +%s.%N )

# tested program
sleep 1

# the current time after the program has finished
# minus the time when we started, in seconds.nanoseconds
elapsed_time=$( date +%s.%N --date="$start_time seconds ago" )

echo elapsed_time: $elapsed_time

这给:

$ ./time_elapsed.sh 
elapsed_time: 1.002257120

如果你已经计算出了时间差值,并且它们小于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)

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