统计工作时长

主要用来计算工作时间时长,去除了休息日以及午休时间 

package net.pakpobox.server.common.service.impl;

import net.pakpobox.server.common.service.CalculateHoursUtilsService;
import net.pakpobox.server.item.repository.HuaWeiCalendarDao;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class CalculateHoursUtilsServiceImpl implements CalculateHoursUtilsService {
    @Autowired
    private HuaWeiCalendarDao huaWeiCalendarDao;

    private static Logger logger = LogManager.getLogger(CalculateHoursUtilsServiceImpl.class);

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //这里的格式可以自己设置

    //求工作时间内的时间间隔
    public float calculateHours(int abh, int abm, int peh, int pem, String beginTime, String endTime, int aeh, int aem, int pbh, int pbm) {
        float h1 = abh + (float) abm / 60;//上午上班时间
        float h4 = peh + (float) pem / 60;//下午下班时间
        float h2 = aeh + (float) aem / 60;//上午下班时间
        float h3 = pbh + (float) pbm / 60;//下午上班时间
        float hoursPerDay = h2 - h1 + h4 - h3;//每天上班小时数
        int daysPerWeek = 7;//每周工作天数
        long milsecPerDay = 1000 * 60 * 60 * 24;//每天的毫秒数
        float hoursPerWeek = hoursPerDay * daysPerWeek;//每星期小时数
        //logger.info("设置的上班时间为:" + abh + ":" + abm + "-" + aeh + ":" + aem
        // + "   " + pbh + ":" + pbm + "-" + peh + ":" + pem);
        //logger.info("每天工作时间为:" + hoursPerDay + "小时");

        //对输入的字符串形式的时间进行转换
        Date t1 = stringToDate(beginTime);//真实开始时间
        Date t2 = stringToDate(endTime);//真实结束时间

        logger.info("设置的开始时间为:" + printDate(t1));
        logger.info("设置的结束时间为:" + printDate(t2));
        //起始时间到终止时间内的假期天数
        int days = (int) ((t2.getTime() - t1.getTime()) / milsecPerDay);
        int holiday = huaWeiCalendarDao.countByDate(dateTostring(t1), dateTostring(t2));
        System.out.println(holiday);
        //对时间进行预处理
        t1 = processBeginTime(abh, abm, h1, h4, milsecPerDay, t1, pbh, pbm, h2, h3);
        t2 = processEndTime(peh, pem, h1, h4, milsecPerDay, t2, aeh, aem, h2, h3);
        logger.info("预处理后的开始时间为:" + printDate(t1));
        logger.info("预处理后的结束时间为:" + printDate(t2));
        //若开始时间晚于结束时间,返回0
        if (t1.getTime() > t2.getTime()) {
            logger.info("总工作时间为:0小时");
            return 0;
        }
        //开始时间到结束时间的完整星期数
        // int weekCount = (int) ((t2.getTime() - t1.getTime()) / (milsecPerDay * 7));
        int weekCount = (int) ((t2.getTime() - t1.getTime()) / milsecPerDay);
        logger.info("时间间隔内共包含了" + weekCount + "个完整的天数");
        float totalHours = 0;

        //totalHours += weekCount * hoursPerWeek - holiday * hoursPerDay;
        //重开始到结束包含的工作时长
        totalHours += (weekCount - holiday + (days - weekCount)) * hoursPerDay;
        //调整结束时间,使开始时间和结束时间在一个星期的周期之内
        //t2.setTime(t2.getTime() - weekCount * 7 * milsecPerDay);
        t2.setTime(t2.getTime() - weekCount * milsecPerDay);
        logger.info("结束时间调整为:" + printDate(t2));
        int dayCounts = 0;//记录开始时间和结束时间之间工作日天数
        //调整开始时间,使得开始时间和结束时间在同一天,或者相邻的工作日内。
        while (t1.getTime() <= t2.getTime()) {
            System.out.println(t1);
            Date temp = new Date(t1.getTime() + milsecPerDay);
            temp = processBeginTime(abh, abm, h1, h4, milsecPerDay, temp, pbh, pbm, h2, h3);
            temp.setHours(t1.getHours());
            temp.setMinutes(t1.getMinutes());
            if (temp.getTime() > t2.getTime()) {
                break;
            } else {
                t1 = temp;
                dayCounts++;
            }
        }
        logger.info("开始时间向后移动了" + dayCounts + "个工作日");
        logger.info("开始时间调整为:" + printDate(t1));
        totalHours += dayCounts * hoursPerDay;

        float hh1 = t1.getHours() + (float) t1.getMinutes() / 60;
        float hh2 = t2.getHours() + (float) t2.getMinutes() / 60;

        //处理开始结束是同一天的情况
        if (t1.getDay() == t2.getDay()) {
            float tt = 0;
            tt = hh2 - hh1;
            //减去中午时间
            if (hh1 >= h1 && hh1 <= h2 && hh2 >= h3) {
                tt = tt - (h3 - h2);
            }
            totalHours += tt;
        } else {
            //处理开始结束不是同一天的情况
            float tt1 = h4 - hh1;
            float tt2 = hh2 - h1;
            //减去中午时间
            if (hh1 <= h2) {
                tt1 = tt1 - (h3 - h2);
            }
            if (hh2 >= h3) {
                tt2 = tt2 - (h3 - h2);
            }
            totalHours += (tt1 + tt2);
        }

        logger.info("总工作时间为:" + totalHours + "小时");
        return totalHours;
    }

    /**
     * 格式化输出时间: yyyy-mm-dd hh:mm:ss 星期x
     *
     * @param t
     * @return
     */
    private String printDate(Date t) {
        String str;
        String xingqi = null;
        switch (t.getDay()) {
            case 0:
                xingqi = "星期天";
                break;
            case 1:
                xingqi = "星期一";
                break;
            case 2:
                xingqi = "星期二";
                break;
            case 3:
                xingqi = "星期三";
                break;
            case 4:
                xingqi = "星期四";
                break;
            case 5:
                xingqi = "星期五";
                break;
            case 6:
                xingqi = "星期六";
                break;
            default:
                break;
        }
        str = format.format(t) + "  " + xingqi;
        return str;
    }

    /**
     * 对结束时间进行预处理,使其处于工作日内的工作时间段内
     *
     * @param t
     * @return
     */
    private Date processEndTime(int peh, int pem, float h1, float h4, Long milsecPerDay, Date t, int aeh, int aem, float h2, float h3) {
        float h = t.getHours() + (float) t.getMinutes() / 60;
        //若结束时间晚于下午下班时间,将其设置为下午下班时间
        if (h >= h4) {
            t.setHours(peh);
            t.setMinutes(pem);
        } else {
            //若结束时间介于中午休息时间,那么设置为上午下班时间
            if (h >= h2 && h <= h3) {
                t.setHours(aeh);
                t.setMinutes(aem);
            } else {
                //若结束时间早于上午上班时间,日期向前推一天,并将时间设置为下午下班时间
                if (t.getHours() <= h1) {
                    t.setTime(t.getTime() - milsecPerDay);
                    t.setHours(peh);
                    t.setMinutes(pem);
                }
            }
        }

        //若结束时间是周末,那么将结束时间向前推移到最近的工作日的下午下班时间,若为华为规定时间
      /*  if (t.getDay() == 0 || t.getDay() == 6) {
            t.setTime(t.getTime() - milsecPerDay * (t.getDay() == 6 ? 1 : 2));
            t.setHours(peh);
            t.setMinutes(pem);
        }*/
        //        //若结束时间是日历休息时间,那么将结束时间向前推移到最近的工作日的下午下班时间,若为规定时间
        int de = huaWeiCalendarDao.loadbyDate(dateTostring(t));
        SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
        if (de > 0) {
            for (int i = 1; i < 365; i++) {
                t = stringTodate(df.format(new Date(t.getTime() - 1 * 24 * 60 * 60 * 1000)));
                int deae = huaWeiCalendarDao.loadbyDate(dateTostring(t));
                if (deae == 0) {
                    t.setTime(t.getTime());
                    t.setHours(peh);
                    t.setMinutes(pem);
                    break;
                }
            }
        }
        return t;
    }

    //获取今日日期
    public String toDayDate() {
        Date d = new Date();
        System.out.println(d);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String dateNowStr = sdf.format(d);
        return dateNowStr;
    }

    /**
     * 对开始时间进行预处理
     *
     * @param t
     * @return
     */
    private Date processBeginTime(int abh, int abm, float h1, float h4, Long milsecPerDay, Date t, int pbh, int pbm, float h2, float h3) {
        float h = t.getHours() + (float) t.getMinutes() / 60;
        //若开始时间晚于下午下班时间,将开始时间向后推一天
        if (h >= h4) {
            t.setTime(t.getTime() + milsecPerDay);
            t.setHours(abh);
            t.setMinutes(abm);
        } else {
            //若开始时间介于中午休息时间,那么设置为下午上班时间
            if (h >= h2 && h <= h3) {
                t.setHours(pbh);
                t.setMinutes(pbm);
            } else {
                //若开始时间早于上午上班时间,将hour设置为上午上班时间
                if (t.getHours() <= h1) {
                    t.setHours(abh);
                    t.setMinutes(abm);
                }
            }
        }
        //若开始时间是周末,那么将开始时间向后推移到最近的工作日的上午上班时间
       /* if (t.getDay() == 0 || t.getDay() == 6) {
            t.setTime(t.getTime() + milsecPerDay * (t.getDay() == 6 ? 2 : 1));
            t.setHours(abh);
            t.setMinutes(abm);
        }*/
        //判断今天日期是否是放假日期,是的话则推后到最近工作日上午上班时间
        //改时间是否为休息日
        int de = huaWeiCalendarDao.loadbyDate(dateTostring(t));
        SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
        System.out.println(de);
        if (de > 0) {
            for (int i = 1; i < 365; i++) {
                t = stringTodate(df.format(new Date(t.getTime() + 1 * 24 * 60 * 60 * 1000)));
                int deae = huaWeiCalendarDao.loadbyDate(dateTostring(t));
                if (deae == 0) {
                    System.out.println(deae);
                    t.setTime(t.getTime());
                    System.out.println(t);
                    t.setHours(abh);
                    t.setMinutes(abm);
                    break;
                }
            }
        }
        return t;
    }


    /**
     * 将字符串形式的时间转换成Date形式的时间
     *
     * @param time
     * @return
     */
    private Date stringToDate(String time) {
        try {
            return format.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将字符串形式的时间转换成Date形式的时间
     *
     * @param time
     * @return
     */
    private Date stringTodate(String time) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            return sdf.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将Date形式的时间转换成String形式的时间
     *
     * @param date
     * @return
     */
    private String dateTostring(Date date) {
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        String str = format.format(date); //2013-01-14
        return str;
    }

}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值