Bash:计算输入的时差(以小时为单位),如"YYYYMMDDHH"



我有两个日期,格式类似:YYYYMMDDHH,并且希望计算这两个日期之间的差异(以小时为单位(。例如

start_date=1996010100
end_date=1996010122

其代表两个日期:1996-01-01 00:00:00和1996-01-01 22:00:00。我想用date来计算小时差,结果应该是22小时。我试过

START=$(date -d "$start_date" +"%s")
END=$(date -d "$end_date" +"%s")
HOURS=$(bc -l <<< "($END - $START) / 3600")

但它失败了。。。那么我该怎么做呢?谢谢

出于性能原因,我们希望限制需要调用的子进程调用的数量:

  • 使用bash子字符串功能将输入转换为可用的日期/时间字符串
  • 使用bash数学替换bc调用

bash子字符串功能,用于将输入分解为可用的日期/时间格式,例如:

# convert to usable date/time format:
$ start_date=1996010100
$ echo "${start_date:0:4}-${start_date:4:2}-${start_date:6:2} ${start_date:8:2}:00:00"
1996-01-01 00:00:00
# convert to epoch/seconds:
$ start=$(date -d "${start_date:0:4}-${start_date:4:2}-${start_date:6:2} ${start_date:8:2}:00:00" +"%s")
$ echo $start
820476000

应用于${end_date}和使用bash数学:

$ end_date=1996010122
$ end=$(date -d "${end_date:0:4}-${end_date:4:2}-${end_date:6:2} ${end_date:8:2}:00:00" +"%s")
$ echo $end
820555200
$ hours=$(( (end - start) / 3600))
$ echo $hours
22

这给我们留下了2个子进程调用($(date ...)(。虽然其他语言/工具(awkperl等(可能会加快速度,但如果需要将结果存储在bash变量中,则至少需要一个子进程调用(即hours=$(awk/perl/??? ...)(。

如果性能真的很重要(例如,需要执行1000次(,请看看这个使用fifo、后台date进程和io重定向的SO答案。。。是的,编码多一点,复杂一点,但对于大量的操作来说也快一点。

busybox date可以完成

start_date=1996010100
end_date=1996010122
START=$(busybox date -D "%Y%m%d%H" -d "$start_date" +"%s")
END=$(busybox date -D "%Y%m%d%H" -d "$end_date" +"%s")
HOURS=$(bc -l <<< "scale=0;($END - $START) / 3600")
echo $HOURS

如果您可以使用像Python这样功能更全面的脚本语言,它将提供更愉快、更易于理解的日期解析体验,并且可能是默认安装的(datetime也是标准的Python库(

采用shell vars 结构

start_date=1996010100
end_date=1996010122
python -c "import datetime ; td = datetime.datetime.strptime('${end_date}', '%Y%m%d%H') - datetime.datetime.strptime('${start_date}', '%Y%m%d%H') ; print(int(td.total_seconds() / 3600))"

结构化以从stdin读取日期和格式代码

echo '%Y%m%d%H' 1996010100 1996010122 | python -c "import datetime,sys ; fmt, date_start, date_end = sys.stdin.read().strip().split() ; td = datetime.datetime.strptime(date_end, fmt) - datetime.datetime.strptime(date_start, fmt) ; print(int(td.total_seconds() / 3600))"

应同时使用Python 3和Python 2.7

此处提供格式代码(1989 C标准(
https://docs.python.org/3/library/datetime.html#strftime-和字符串格式代码

代表两个日期:1996-01-00:00:00

因此,如果它代表它,请将其转换为该形式。

start_date=1996010100
start_date=$(sed -E 's/(....)(..)(..)(..)/1-2-3 4:00:00/' <<<"$start_date")
start=$(date -d "$start_date" +"%s")

与end相同。

最简单的方法是安装"dateutils";使用该命令

sudo apt-get install dateutils

运行以下命令以秒为单位获得差异:

dateutils.ddiff -i '%Y%m%d%H%M%S' 20200817040001 20210817040101

输出:

31536060s

下一步:只需除以86400就可以得到天数,或者类似的小时和分钟数:(

最新更新