免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: whoislp
打印 上一主题 下一主题

[文本处理] 统计工时 [复制链接]

论坛徽章:
39
辰龙
日期:2013-08-21 15:45:192015亚冠之广州富力
日期:2015-05-12 16:34:52亥猪
日期:2015-03-03 17:22:00申猴
日期:2015-03-03 17:21:37未羊
日期:2014-10-10 13:45:41戌狗
日期:2014-06-17 09:53:29巨蟹座
日期:2014-06-12 23:17:17双鱼座
日期:2014-06-10 12:42:44寅虎
日期:2014-06-09 12:52:172015亚冠之卡尔希纳萨夫
日期:2015-05-24 15:24:35黄金圣斗士
日期:2015-12-02 17:25:0815-16赛季CBA联赛之吉林
日期:2017-06-24 16:43:52
11 [报告]
发表于 2013-07-16 17:34 |只看该作者
本帖最后由 关阴月飞 于 2013-07-16 17:38 编辑

回复 7# zooyo

版主强大!学习了,根据思路,加了几个判断,以防出现打卡早退现象时不会计算工时:
  1. #!/usr/bin/awk -f
  2. #定义函数:将时间格式输入转换成数值输出
  3. function atoi(s){split(s,a,":");return a[1]*3600+a[2]*60+a[3]}

  4. #定义函数:数值输入转为时间格式输出
  5. function itoa(n){i=sprintf("%02d:%02d:%02d",int(n/3600),int(n%3600/60),n%60);return i}

  6. #设置上午工作时间start_s --> end_s, 下午工作时间 start_x --> end_x,加班开始时间 ot
  7. BEGIN{h=3600; start_s=8*h; end_s=12*h; start_x=13.5*h; end_x=17.5*h; ot=18*h}
  8. {
  9.     #获取上班打卡记录$2 下班打卡记录$3, 并使用自定义函数转换成数值
  10.     j=atoi($2);
  11.     k=atoi($3);

  12.     #如果存在上班提前打卡(即上班打卡时间早于start_s(8:00)),则将打卡时间设为8:00
  13.     if(j<start_s)
  14.         j=start_s;

  15.     #判断是否存在早退(分开上下午两个时间段及是否加班分别判断)
  16.    #上午班判断
  17.    #如果早于end_s 12:00打下班卡,直接计算工时.
  18.     if (k<=end_s){
  19.         sum+=k-j;
  20.         print $0,itoa(k-j);
  21.         next;
  22.     }
  23.     #如果在start_x 13:30 之前打下班卡,将下班打卡时间设为12:00
  24.      if (k<=start_x){
  25.         k=end_s
  26.         sum+=k-j;
  27.         print $0,itoa(k-j);
  28.         next;
  29.     }
  30.    
  31.     #下午班判断
  32.      #如果在end_x 17:30 或之前打下班卡,计算工时时减去午休时间 1.5h
  33.      if (k<=end_x){
  34.         sum+=k-j-1.5*h;
  35.         print $0,itoa(k-j-1.5*h);
  36.         next;
  37.     }

  38.      #如果在ot  18:00 或之前打下班卡,将下班打卡时间设为17:30  且计算工时时减去1.5h
  39.      if (k<=ot){
  40.         k=end_x
  41.         sum+=k-j-1.5*h;
  42.         print $0,itoa(k-j-1.5*h);
  43.         next;
  44.     }
  45.    
  46.     #加班判断
  47.     # 如果在ot  18:00 之后打下班卡,视为加班,  计算工时时减去2h
  48.     if(k>ot){
  49.         sum+=k-j-2*h;
  50.         print $0,itoa(k-j-2*h);
  51.     }
  52. }
  53. END{
  54.     print "avg: "itoa(int(sum/NR))
  55. }
复制代码

论坛徽章:
1
射手座
日期:2014-03-10 14:24:52
12 [报告]
发表于 2013-07-16 17:42 |只看该作者
真心强大,逻辑清晰!学习!

论坛徽章:
71
15-16赛季CBA联赛之同曦
日期:2018-08-23 15:41:42辰龙
日期:2014-08-15 09:07:43狮子座
日期:2014-06-03 13:55:33亥猪
日期:2014-06-02 11:17:08巨蟹座
日期:2014-05-06 10:02:03午马
日期:2014-05-04 08:18:27亥猪
日期:2014-04-29 11:11:32技术图书徽章
日期:2014-04-24 15:51:26技术图书徽章
日期:2014-04-17 11:01:53辰龙
日期:2014-04-15 12:45:46亥猪
日期:2014-04-11 09:06:23射手座
日期:2014-04-01 15:28:10
13 [报告]
发表于 2013-07-16 17:46 |只看该作者
凭啥,18:00后不算工时

论坛徽章:
13
丑牛
日期:2013-08-16 15:08:22技术图书徽章
日期:2013-11-26 10:13:40双鱼座
日期:2013-11-08 15:03:26戌狗
日期:2013-11-08 13:52:30技术图书徽章
日期:2013-11-05 14:06:30戌狗
日期:2013-10-31 11:45:42CU十二周年纪念徽章
日期:2013-10-24 15:41:34天秤座
日期:2013-10-11 14:55:08子鼠
日期:2013-09-26 19:36:35水瓶座
日期:2013-09-26 17:44:56午马
日期:2013-08-26 10:24:23丑牛
日期:2013-08-19 14:43:22
14 [报告]
发表于 2013-07-16 17:50 |只看该作者
回复 13# zhaopingzi


    算工时,但不给你算加班费

论坛徽章:
6
摩羯座
日期:2013-08-24 10:43:10狮子座
日期:2013-08-25 10:27:06天秤座
日期:2013-09-11 20:28:44午马
日期:2014-09-28 16:06:0015-16赛季CBA联赛之八一
日期:2016-12-19 13:55:0515-16赛季CBA联赛之天津
日期:2016-12-20 14:01:23
15 [报告]
发表于 2013-07-16 21:30 |只看该作者
  1. awk  '{i=$2;o=$3;gsub(/:/,"",i);gsub(/:/,"",o);if(int(i)<80000){$2="08:00:00"};if(int(o)>173000 && int(o)<=180000){$3="17:30:00"};if(int(o)>180000){x=1800};t1=$1" "$2;t2=$1" "$3;gsub(/-|:/," ",t1);gsub(/-|:/," ",t2);work=mktime(t2)-mktime(t1)-x-5400;print $1,work/3600,"hours"}' file
复制代码
中午12点前下班的情况就没考虑进去。




论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
16 [报告]
发表于 2013-07-16 22:59 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
17 [报告]
发表于 2013-07-16 23:01 |只看该作者
本帖最后由 ryr1990 于 2013-07-16 23:03 编辑

回复 7# zooyo


   我运行是报错了: syntax error near unexpected token `s'
这个一般是什么错。请教一下。

论坛徽章:
0
18 [报告]
发表于 2013-07-17 14:11 |只看该作者
回复 3# zooyo
循环里面再加上12:00-13:30 就更完美了

   

论坛徽章:
0
19 [报告]
发表于 2013-07-17 15:31 |只看该作者
用awk写了一个,楼主可以参考:
function cal_time(start, end)
{
    split(start, s_a, ":"
    split(end, e_a, ":"
    d=(e_a[1]-s_a[1])*60 + e_a[2]-s_a[2]
   
    #before 8:00
    if(s_a[1]<{
        temp=(8-s_a[1])*60-s_a[2]
        d-=temp
    }
   
    #12:00~13:30
    m_s=(s_a[1]<12?12*60:s_a[1]*60+s_a[2])
    m_e=(e_a[1]*60+e_a[2]>13*60+30?13*60+30:e_a[1]*60+e_a[2])
    if(m_e>m_s){
        d-=(m_e-m_s)
    }

    #17:30~18:00
    m_s=(s_a[1]*60+s_a[2]<17*60+30?17*60+30:s_a[1]*60+s_a[2])
    m_e=(e_a[1]>=18?18*60:e_a[1]*60+e_a[2])
    if(m_e>m_s){
        d-=(m_e-m_s)
    }

    return d
}

BEGIN{
    total_m=0
}

{
    start=$2
    end=$3
    d=cal_time(start, end)
    print int(d/60)":"d%60
    total_m+=d
}

END{
    print "avg:"int(total_m/NR/60)":"int(total_m/NR)%60
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP