我有两个日期,格式类似: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 ...)
(。虽然其他语言/工具(awk
、perl
等(可能会加快速度,但如果需要将结果存储在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就可以得到天数,或者类似的小时和分钟数:(