我有一个日期,结束时间和十进制格式的持续时间的文件,我需要计算开始时间。该文件看起来像:
20140101;1212;1.5
20140102;1515;1.58
20140103;1759;.69
20140104;1100;12.5
...
时间12:12的持续时间1.5表示一个半小时,开始时间为12:12 - 1:30 = 10:42 AM或11:00 - 12.5 = 11:00 - 12:30 = 22:30 PM。有没有一种简单的方法来计算Awk中的这种时间差异,或者它是一个好的“分裂 - 乘法 - 减去 - 并且 - 处理 - 一天 - 再次自我打破?”
由于值以小时和分钟为单位,因此只有分钟很重要且秒可以被丢弃,例如持续时间1.58表示1:34,剩余的0.8秒可以被丢弃。
我正在使用GNU Awk 4.1.3
答案 0 :(得分:2)
我强烈建议使用支持日期时间计算的编程语言,因为计算可能会非常棘手,因为夏令时会发生变化。例如,您可以使用Python:
start_times.py :
import csv
from datetime import datetime, timedelta
with open('input.txt', 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=';', quotechar='|')
for row in reader:
end_day = row[0]
end_time = row[1]
# Create a datetime object
end = datetime.strptime(end_day + end_time, "%Y%m%d%H%M")
# Translate duration into minutes
duration=float(row[2])*60
# Calculate start time
start = end - timedelta(minutes=duration)
# Column 3 is the start day (can differ from end day!)
row.append(start.strftime("%Y%m%d"))
# Column 4 is the start time
row.append(start.strftime("%H%M"))
print ';'.join(row)
执行命令
python start_times.py
输出:
20140101;1212;1.5;20140101;1042
20140102;1515;1.58;20140102;1340
20140103;1759;.69;20140103;1717
20140104;1100;12.5;20140103;2230 <-- you see, the day matters!
以上示例使用的是系统的时区。如果输入数据指的是不同的时区,Pyhon的datetime模块允许指定它。
答案 1 :(得分:2)
当您使用gawk
时,请使用其原生time functions
:
gawk -F\; '{tmst=sprintf("%s %s %s %s %s 00",\
substr($1,1,4),\
substr($1,5,2),\
substr($1,7,2),\
substr($2,1,2),\
substr($2,3,2))
t1=mktime(tmst)
seconds=sprintf("%f",$3)+0
seconds*=60*60
difference=strftime("%H%M",t1-seconds)
print $0""FS""difference}' file
<强>结果:
20140101;1212;1.5;1042
20140102;1515;1.58;1340
20140103;1759;.69;1717
20140104;1100;12.5;2230
检查:https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html
<强>解释强>
tmst=sprintf(..)
:用于从文件中创建日期字符串
符合datespec
mktime
函数YYYY MM
DD HH MM SS [DST]
。t1=mktime(tmst)
:将datespec转换为可以的时间戳
处理 gawk
(自1开始经过的秒数)
1970年1月)seconds=sprintf("%f",$3)+0
:将第三个字段转换为浮动。seconds*=60*60
:将小时数(浮点数)转换为秒数。difference=strftime("%H%M",t1-seconds)
:获得改变
human maner,小时一分钟。答案 2 :(得分:1)
我会做这样的事情:
awk 'BEGIN{FS=OFS=";"}
{ h=substr($2,0,2); m=substr($2,3,2); mins=h*60 + m; diff=mins - $3*60;
print $0, int(diff/60) ":" int(diff%60)
}' file
也就是说,将所有内容转换为分钟,然后再转换为小时/分钟。
$ awk 'BEGIN{FS=OFS=";"}{h=substr($2,0,2); m=substr($2,3,2); mins=h*60 + m; diff=mins - $3*60; print $0, int(diff/60) ":" int(diff%60)}' a
20140101;1212;1.5;10:42
20140102;1515;1.58;13:40
20140103;1759;.69;17:17