awk并从结束时间和持续时间计算开始时间

时间:2015-11-05 10:14:32

标签: time awk

我有一个日期,结束时间和十进制格式的持续时间的文件,我需要计算开始时间。该文件看起来像:

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

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