Bash脚本:计算两个时间之间的分钟差异

17

我有两个时间字符串,例如"09:11"和"17:22",它们在同一天(格式为hh:mm)。我该如何计算这两个时间之间的分钟差异?

标准的date库能做到这一点吗?

示例:

#!/bin/bash

MPHR=60    # Minutes per hour.

CURRENT=$(date -u -d '2007-09-01 17:30:24' '+%F %T.%N %Z')
TARGET=$(date -u -d'2007-12-25 12:30:00' '+%F %T.%N %Z')

MINUTES=$(( $(diff) / $MPHR ))

如果已知小时和分钟的格式为hh:mm,是否有更简单的方法来完成这个任务?

6个回答

21

一个纯粹的 解决方案:

old=09:11
new=17:22

# feeding variables by using read and splitting with IFS
IFS=: read old_hour old_min <<< "$old"
IFS=: read hour min <<< "$new"

# convert hours to minutes
# the 10# is there to avoid errors with leading zeros
# by telling bash that we use base 10
total_old_minutes=$((10#$old_hour*60 + 10#$old_min))
total_minutes=$((10#$hour*60 + 10#$min))

echo "the difference is $((total_minutes - total_old_minutes)) minutes"

另一种解决方案是使用date(我们处理小时/分钟,因此日期不重要)


old=09:11
new=17:22

IFS=: read old_hour old_min <<< "$old"
IFS=: read hour min <<< "$new"

# convert the date "1970-01-01 hour:min:00" in seconds from Unix EPOCH time
sec_old=$(date -d "1970-01-01 $old_hour:$old_min:00" +%s)
sec_new=$(date -d "1970-01-01 $hour:$min:00" +%s)

echo "the difference is $(( (sec_new - sec_old) / 60)) minutes"

请查看http://en.wikipedia.org/wiki/Unix_time


在日期解决方案中,我得到以下输出:用法:日期[-jnu] [-d dst] [-r seconds] [-t west] [-v[+ | -]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format] - gorn
第一个可以工作 :) 谢谢!但我认为日期使用不正确,因为我收到了使用错误。 - gorn
“date” 的解决方案对我来说运行良好。最后一次算术操作中缺少了一些圆括号(已经更正)。date(GNU coreutils)8.20。 - Gilles Quénot
有些人可能会发现 date -ud '0000-01-01 10 seconds - 0 seconds' '+%FT%T'; 也很有趣,但如果用作当前时间差异的计算,它可能会返回不正确的时间。 - Artfaith

19

我会将日期转换为UNIX时间戳;您可以相减以获取秒数差,然后除以60:

#!/bin/bash

MPHR=60    # Minutes per hour.

CURRENT=$(date +%s -d '2007-09-01 17:30:24')
TARGET=$(date +%s -d'2007-12-25 12:30:00')

MINUTES=$(( ($TARGET - $CURRENT) / $MPHR ))

1
我将这个代码封装成了一个bash函数,使用dt() { echo $(( ( $(date +%s -d "$2") - $(date +%s -d "$1") ) / 60 )) ; }。然后我只需要输入dt '2007-09-01 17:30:24' '2007-12-25 12:30:00'就可以得到答案了。 - Michael Anderson
应该是每分钟的秒数吧? - Azor Ahai -him-
可能吧。还是60,但名字会更有意义 :) - chepner

9

这是我实现它的方法:

START=$(date +%s);
sleep 1; # Your stuff
END=$(date +%s);
echo $((END-START)) | awk '{printf "%d:%02d:%02d", $1/3600, ($1/60)%60, $1%60}'

非常简单,从开始时的秒数减去结束时的秒数,打印出分钟:秒钟的差异。


7
我在寻找一个秒数的解决方案。在这里找到了: 如何在Bash脚本中计算时间差?
#!/bin/bash
string1="10:33:56"
string2="10:36:10"
StartDate=$(date -u -d "$string1" +"%s")
FinalDate=$(date -u -d "$string2" +"%s")
date -u -d "0 $FinalDate sec - $StartDate sec" +"%H:%M:%S"

在Gilles的解决方案中,我添加了秒:

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;
}

4
MPHR=60
CURRENT=09:11
TARGET=17:22
echo $(( ( 10#${TARGET:0:2} - 10#${CURRENT:0:2} ) * MPHR + 10#${TARGET:4} - 10#${CURRENT:4} ))

3
STARTTIME=$(date +%s)

你的代码:

ENDTIME=$(date +%s)
secs=$(($ENDTIME - $STARTTIME))
printf 'Elapsed Time %dh:%dm:%ds\n' $(($secs/3600)) $(($secs%3600/60)) $(($secs%60)) 

1
我认为你应该编辑你的答案,以便更易于阅读和理解。此外,包括额外的评论来澄清你的答案。 - ZygD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接