ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java日期工具类--获取两个日期之间的工作日天数(只去除周六日,未去除节假日)

2022-01-17 18:32:28  阅读:710  来源: 互联网

标签:WEEK sdate java get 日期 去除 Calendar edate DAY


获取两个日期之间的工作日天数 (只去除周六日,未去除节假日)

其他参考资料:

两个日期之间的工作日计算工具类
https://www.cnblogs.com/zzlp/p/5166605.html
https://blog.csdn.net/weixin_30731305/article/details/99756422

 

方法1、使用循环的方式遍历两个日期的每一天,当日期不属于周六日时, 工作日 + 1   方法2、 1、如果两个时间在同一周,且都不是周末日期,直接返回  时间差,提高执行效率 2、不是同一周时,将开始日期和结束日期都设置到下个周一,计算这两个周一之间的工作日天数。   计算开始日期到下周一,结束日期到下周一的偏移天数。 获取到两个偏移天数的差值。   总的工作日天数 = 将获取到的工作日天数 + 偏移天数差值   日期工具类 DateUtils.java  
public class DateUtils {


    /**
     * 获取两个时间之内的工作日时间(只去掉两个日期之间的周末时间,法定节假日未去掉) 时间精确到日
     *
     * @param startDate
     *            -起始时间
     * @param endDate
     *            -结束时间
     * @return Long型时间差对象
     */
    public static int getWorkdayTimeInDate(Date startDate, Date endDate) {
        long start = startDate.getTime();
        long end = endDate.getTime();
        // 如果起始时间大于结束时间,将二者交换
        if (start > end) {
            long temp = start;
            start = end;
            end = temp;
        }
        // 根据参数获取起始时间与结束时间的日历类型对象
        Calendar sdate = Calendar.getInstance();
        Calendar edate = Calendar.getInstance();
        sdate.setTimeInMillis(start);
        edate.setTimeInMillis(end);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


        try {
            sdate.setTime(sdf.parse(sdf.format(sdate.getTime())));
            edate.setTime(sdf.parse(sdf.format(edate.getTime())));
        } catch (ParseException e) {
            e.printStackTrace();
        }


        // 如果两个时间在同一周并且都不是周末日期,则直接返回时间差,增加执行效率
        if (sdate.get(Calendar.YEAR) == edate.get(Calendar.YEAR)
            && sdate.get(Calendar.WEEK_OF_YEAR) == edate.get(Calendar.WEEK_OF_YEAR)
            && sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY
            && edate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && edate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            long between_days = (end - start) / (1000 * 3600 * 24);
            return Integer.parseInt(String.valueOf(between_days));
        }


        // 防止开始日期在周五,结束日期在周日情况下,计算间隔天数不准确问题,开始或结束日期为周六日时,
        // 开始日期周六日,设置为下周一。
        if (sdate.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            sdate.add(Calendar.DAY_OF_MONTH, 1);
        }
        if (sdate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            // 开始日期在周六日时,设置日期为周一
            sdate.add(Calendar.DAY_OF_MONTH, 2);
        }
        start = sdate.getTimeInMillis();
        // 结束日期为周六日时,设置为周五
        if (edate.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            edate.add(Calendar.DAY_OF_MONTH, -2);
        }
        if (edate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            edate.add(Calendar.DAY_OF_MONTH, -1);
        }
        end = edate.getTimeInMillis();


        // 首先取得起始日期与结束日期的下个周一的日期
        Calendar snextM = getNextMonday(sdate);
        Calendar enextM = getNextMonday(edate);
        // 获取这两个周一之间的实际天数
        int days = 0;
        try {
            days = daysBetween(snextM.getTime(), enextM.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 获取这两个周一之间的工作日数(两个周一之间的天数肯定能被7整除,并且工作日数量占其中的5/7)
        int workdays = days / 7 * 5;
        // 获取开始时间的偏移量
        long scharge = 0;
        sdate.setTimeInMillis(start);
        edate.setTimeInMillis(end);
        if (sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && sdate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            // 只有在开始时间为非周末的时候才计算偏移量
            scharge += (7 - sdate.get(Calendar.DAY_OF_WEEK)) * 24 * 3600000;
            scharge -= sdate.get(Calendar.HOUR_OF_DAY) * 3600000;
            scharge -= sdate.get(Calendar.MINUTE) * 60000;
            scharge -= sdate.get(Calendar.SECOND) * 1000;
            scharge -= sdate.get(Calendar.MILLISECOND);
        }
        // 获取结束时间的偏移量
        long echarge = 0;
        if (edate.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
            && edate.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            // 只有在结束时间为非周末的时候才计算偏移量
            echarge += (7 - edate.get(Calendar.DAY_OF_WEEK)) * 24 * 3600000;
            echarge -= edate.get(Calendar.HOUR_OF_DAY) * 3600000;
            echarge -= edate.get(Calendar.MINUTE) * 60000;
            echarge -= edate.get(Calendar.SECOND) * 1000;
            echarge -= edate.get(Calendar.MILLISECOND);
        }
        // 计算最终结果,具体为:workdays加上开始时间的时间偏移量,减去结束时间的时间偏移量
        long between_days = workdays + (scharge - echarge) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }


    /**
     * 获取下周一
     *
     * @param calendar
     *            指定日期
     * @return
     */
    private static Calendar getNextMonday(Calendar calendar) {
        int addnum = 9 - calendar.get(Calendar.DAY_OF_WEEK);
        if (addnum == 8) {
            addnum = 1;// 周日的情况
        }
        calendar.add(Calendar.DATE, addnum);
        return calendar;
    }


    /**
     *
     * 计算两个日期之间相差的天数
     *
     * @param smdate
     *            较小的时间
     *
     * @param bdate
     *            较大的时间
     *
     * @return 相差天数
     *
     * @throws ParseException
     *
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);


        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();


        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }
}

 

标签:WEEK,sdate,java,get,日期,去除,Calendar,edate,DAY
来源: https://www.cnblogs.com/gne-hwz/p/15814744.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有