我正在尝试计算格式如下的日期之间的时差:
dd / mm / YY; hh:mm:ss; dd / mm / YY; hh:mm:ss (第一对dd / mm / YY; hh:mm:ss指出开始日期和第二对夫妇是 结束日期)
我希望输出如下:
dd / mm / YY; hh:mm:ss; dd / mm / YY; hh:mm:ss; hh:mm:ss ,其中添加的hh:mm:ss是两个日期之间的时差。
以下是一个例子:
end
我用 gsub,mktime和awk 尝试了很多东西,以便格式化日期,但没有什么是足够有效的(格式和分割操作太多)。
这是我的尝试:
INPUT:
12/11/15;20:04:09;13/11/15;08:46:26
13/11/15;20:05:34;14/11/15;08:42:04
14/11/15;20:02:47;16/11/15;08:44:43
OUTPUT:
12/11/15;20:04:09;13/11/15;08:46:26;12:42:17
13/11/15;20:05:34;14/11/15;08:42:04;12:36:30
14/11/15;20:02:47;16/11/15;08:44:43;36:41:56
你有什么建议? 谢谢:))
答案 0 :(得分:1)
您可以尝试此操作并保存一些gsub
和substr
来电:
awk -F'[:;/]' '{d1=mktime("20"$3" "$2" "$1" "$4" "$5" "$6);
d2=mktime("20"$9" "$8" "$7" "$10" "$11" "$12);
delta = d2-d1
sec = delta%60
min = (delta - sec)%3600/60
hrs = int(delta/3600)
print $0";"(hrs < 10 ? "0"hrs : hrs)\
":"(min < 10 ? "0"min : min)\
":"(sec < 10 ? "0"sec : sec);}' time.txt
由于我们不能使用strftime
(坦克到Ed Morton),我们必须处理小时&gt; 23或小时/分钟/秒< 10手动。
上面的代码输出:
14/11/15;20:02:47;16/11/15;08:44:43;36:41:56
14/11/15;20:02:47;14/11/15;20:02:48;00:00:01
输入
14/11/15;20:02:47;16/11/15;08:44:43
14/11/15;20:02:47;14/11/15;20:02:48
答案 1 :(得分:1)
如果没有mktime(),你不能强有力地完成这项工作,因为时差计算需要考虑闰日,闰秒等。我认为你不能比这更有效地做到这一点:
$ cat tst.awk
BEGIN { FS="[/;:]" }
{
d1 = mktime("20"$3" "$2" "$1" "$4" "$5" "$6)
d2 = mktime("20"$9" "$8" "$7" "$10" "$11" "$12)
delta = d2 - d1
hrs = int(delta/3600)
min = int((delta - hrs*3600)/60)
sec = delta - (hrs*3600 + min*60)
printf "%s;%02d:%02d:%02d\n", $0, hrs, min, sec
}
$ awk -f tst.awk file
12/11/15;20:04:09;13/11/15;08:46:26;12:42:17
13/11/15;20:05:34;14/11/15;08:42:04;12:36:30
14/11/15;20:02:47;16/11/15;08:44:43;36:41:56
注意 - 您不能使用strftime()[单独]来计算小时,分钟和秒,因为当您的delta值超过1天时,strftime()将返回与时间相关的小时,分钟和秒在该delta的最后一天,而不是与整个delta相关联的hrs,min和sec的总数。
答案 2 :(得分:0)
你所要求的将是相当棘手的传统awk。
当然,gawk(GNU awk)支持mktime,但其他awk实现则不支持。但是你可以直接在bash中执行此操作,依靠date
命令进行转换。此解决方案使用BSD日期(因此它可以在FreeBSD,NetBSD,OpenBSD,OSX等中使用)。
while IFS=\; read date1 time1 date2 time2; do
stamp1=$(date -j -f '%d/%m/%y %T' "$date1 $time1" '+%s')
stamp2=$(date -j -f '%d/%m/%y %T' "$date2 $time2" '+%s')
d=$((stamp2-stamp1))
printf '%s;%s;%s;%s;%02d:%02d:%02d\n' "$date1" "$time1" "$date2" "$time2" $(( (d/3600)%60)) $(( (d/60)%60 )) $((d%60))
done < dates.txt
结果:
12/11/15;20:04:09;13/11/15;08:46:26;12:42:17
13/11/15;20:05:34;14/11/15;08:42:04;12:36:30
14/11/15;20:02:47;16/11/15;08:44:43;36:41:56
当然,如果您使用的是非BSD操作系统,则可能必须安装bsddate(如果可用)才能获得此功能,或者使用您手头的工具找出如何获得相同的功能。< / p>