解决两个日期之间计算工作日实现2

来源:互联网 发布:linux kill函数 编辑:程序博客网 时间:2024/06/16 02:26

前提:业务场景  最近公司业务中需要根据一段时间内 根据工作日去筛选计算一个完整周期时长 超时情况分为以下四种(正常,即将到期,延误,严重延误)简单实现 非礼勿喷

两种实现:

1.第一种是 计算     根据传入  时间戳 加上指定天数 得出最终结束日时间戳(不计入周末时间 前者   后者顺延)  


2.第二种是 计算     两个时间戳 相差工作日 毫秒数 (不计入周末时间 前者  后者顺延)  


准备条件: 需要有一张日历维护表 维护 年数据

CREATE TABLE `calendar_day` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID主键,自增',
  `date_time` int(10) DEFAULT NULL COMMENT '具体日期',
  `date_flag` int(4) DEFAULT NULL COMMENT '类型标识码表(CBPMDateType)',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_ti` bigint(13) DEFAULT NULL COMMENT '创建时间',
  `create_user_id` int(11) DEFAULT NULL COMMENT '创建者',
  `modify_ti` bigint(13) DEFAULT NULL COMMENT '修改时间',
  `modify_user_id` int(11) DEFAULT NULL COMMENT '修改者',
  `version` int(11) DEFAULT '0' COMMENT '版本默认为0,-1为删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=804 DEFAULT CHARSET=utf8 COMMENT='日历表';


当前 注意的类型码表标识 项目喜欢 使用通过 码表标识 常用记录问题  所以单独解释下  当前类型对应 一下四个值 标识节假日及其上班

CBPMDateType1001正常工作日1002节假日上班2001正常节假日2002工作日休息


第一种实现 (加上工作日计算):

逻辑  : 当前 是工作日直接计算 ,如果是休息日 则取最近一个工作日计算(往后推),参数解释:1.开始时间毫秒数  2.相加天数


 public Long selectDateAdd(Long startDay, int days) {
        logger.info("selectDateAdd  startDay=={},  days=={}", startDay, days);
        Map<String, Object> paraMap = new HashMap<String, Object>();
        String startDayStr = DateUtil.timestamp2String(startDay, "yyyyMMdd HH:ss:mm");
        paraMap.put("startDay", Integer.valueOf(startDayStr.substring(0, 8)) - 1);
        paraMap.put("days", days-1);
        CalendarDay calendarDay = calendarDayMapper.selectDateAdd(paraMap);
        if (null == calendarDay) {
            logger.info("暂无维护日期");
            return startDay + (long) days * 24 * 60 * 60 * 1000;
        }
        CalendarDay startDayCalendarDay = calendarDayMapper
            .selectByDate(Integer.valueOf(startDayStr.substring(0, 8)));
        String endDayStr;
        if (startDayCalendarDay != null) {


            if (startDayCalendarDay.getDateFlag()
                .intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1001
                || startDayCalendarDay.getDateFlag()
                    .intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1002) {
                //开始日上班
                logger.info("开始日上班");
                endDayStr = calendarDay.getDateTime().toString() + startDayStr.substring(8);
            } else {
                //开始日不上班
                logger.info("开始日不上班");
                endDayStr = calendarDay.getDateTime().toString() + " 23:59:59";
            }
            return DateUtil.string2Timestamp(endDayStr, "yyyyMMdd HH:ss:mm");
        } else {
            return startDay + (long) days * 24 * 60 * 60 * 1000;
        }
    }

第二种实现:计算 两个时间戳 相差工作日 毫秒数 

逻辑 :    参数 1.开始时间戳  2.结束时间戳

  public Long selectDateDiff(Long startDay, Long endDay) {
        logger.debug("startDay {} , endDay {}",startDay,endDay);
        CalendarDay startDayCalendarDay = calendarDayMapper.selectByDate(Integer
            .valueOf(DateUtil.timestamp2String(startDay, "yyyyMMdd HH:ss:mm").substring(0, 8)));
        CalendarDay endDayCalendarDay = calendarDayMapper.selectByDate(Integer
            .valueOf(DateUtil.timestamp2String(endDay, "yyyyMMdd HH:ss:mm").substring(0, 8)));
        if (null == startDayCalendarDay || endDayCalendarDay == null) {
            logger.info("暂无维护日期");
            return endDay - startDay;
        }
        Long startSec = 0l;//开始那天剩余毫秒数
        Long endSec = 0l;//结束那天剩余毫秒数
        Integer startDayInter = Integer
            .valueOf(DateUtil.timestamp2String(startDay, "yyyyMMdd HH:ss:mm").substring(0, 8));
        Integer endDayInter = Integer
            .valueOf(DateUtil.timestamp2String(endDay, "yyyyMMdd HH:ss:mm").substring(0, 8));
        if (startDayInter.intValue() == endDayInter.intValue()) {
            //开始结束是同一天
            if (startDayCalendarDay.getDateFlag()
                .intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1001
                || startDayCalendarDay.getDateFlag()
                    .intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1002) {
                logger.info("开始结束是同一天  上班");
                return endDay - startDay;
            } else {
                logger.info("开始结束是同一天  休息");
                return 0l;
            }
        }


        if (startDayCalendarDay.getDateFlag().intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1001
            || startDayCalendarDay.getDateFlag()
                .intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1002) {
            //开始日上班
            logger.info("开始日上班");
        } else {
            //开始日休息
            logger.info("开始日休息");
            String startDayEndStr = startDayInter.toString() + " 23:59:59";
            startSec = DateUtil.string2Timestamp(startDayEndStr, "yyyyMMdd HH:ss:mm") - startDay;
        }     


        if (endDayCalendarDay.getDateFlag().intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1001
            || endDayCalendarDay.getDateFlag()
                .intValue() == CBpmConstant.CBPM_DATA_TIME_TYPE_1002) {
            //结束日上班
            logger.info("结束日上班");
        } else {
            //结束日休息
            logger.info("结束日休息");
            endSec = endDay - DateUtil.string2Timestamp(endDayInter.toString() + " 00:00:00",
                "yyyyMMdd HH:ss:mm");
        }
        Map<String, Object> paraMap = new HashMap<String, Object>();
        paraMap.put("startDay", startDayInter);
        paraMap.put("endDay", endDayInter);
        Long days = calendarDayMapper.selectDateDiff(paraMap);
        return endDay - startDay - startSec - endSec - (long) days * 24 * 60 * 60 * 1000;
    }

备注 :

 最后位置 计算方便理解:

开始时间 -结束时间 -休息时间到23.59.59 -结束到0.0.0-两者相距的工作日*毫秒数


备注:

相关sql 仅供参考

/**
     * 获取一个内的所有节假日数据
     * @param month
     * @return
     */
    List<CalendarDay> selectListMonth(String month);


    /**
     * @param paraMap
     * @return  工作日加法
     */
    CalendarDay selectDateAdd(Map<String, Object> paraMap);


    /**查询当日情况
     * @param startDay
     * @return
     */
    CalendarDay selectByDate(Integer startDay);


    /**统计日期差工作日
     * @param paraMap
     * @return
     */
    Long selectDateDiff(Map<String, Object> paraMap);


 <select id="selectListMonth" parameterType="java.lang.String" resultMap="BaseResultMap" >
   SELECT 
cd.*
from cbpm.calendar_day cd 
where SUBSTR(cd.date_time FROM 1 FOR 6) =  #{month,jdbcType=INTEGER}
   </select>

   <select id="selectDateAdd" parameterType="java.util.Map" resultMap="BaseResultMap" >
SELECT 
<include refid="Base_Column_List" />
FROM calendar_day cd 
where cd.date_flag in (${@com.jsb.cbpm.common.CBpmConstant@CBPM_DATA_TIME_TYPE_1001},
${@com.jsb.cbpm.common.CBpmConstant@CBPM_DATA_TIME_TYPE_1002})
and cd.date_time > #{startDay,jdbcType=INTEGER}
 ORDER BY date_time asc limit #{days,jdbcType=INTEGER},1
   </select>
   <select id="selectByDate" parameterType="java.lang.Integer" resultMap="BaseResultMap" >
SELECT 
<include refid="Base_Column_List" />
FROM calendar_day cd 
where  cd.date_time = #{startDay,jdbcType=INTEGER} limit 1
   </select>
   
   
<select id="selectDateDiff" parameterType="java.util.Map" resultType="java.lang.Long" >
SELECT count(*) 
FROM calendar_day cd 
where   cd.date_flag in (${@com.jsb.cbpm.common.CBpmConstant@CBPM_DATA_TIME_TYPE_2001},
${@com.jsb.cbpm.common.CBpmConstant@CBPM_DATA_TIME_TYPE_2002})
and cd.date_time > #{startDay,jdbcType=INTEGER} 
and #{endDay,jdbcType=INTEGER} > cd.date_time
   </select>


当前引用到一些封装的日期工具类,可以参考链接去看下


http://blog.csdn.net/lgd_guangdong/article/details/78651589

原创粉丝点击