zoukankan      html  css  js  c++  java
  • Java计算工作日的工具类

      有时候需要根据工作日计算指定的日期,也就是需要排除周六日。

    1.  初版代码如下:

    package cn.xm.exam.utils;
    
    import java.util.Calendar;
    import java.util.Date;
    
    import org.apache.commons.lang.time.DateFormatUtils;
    
    public class WorkDayCalculateUtils {
        public static void main(String[] args) {
            Date date = getDate(new Date(), -7);
            System.out.println(DateFormatUtils.format(date, "yyyy-MM-dd"));
        }
    
        public static Date getDate(Date currentDate, int days) {
            if (days == 0) {
                return currentDate;
            }
    
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(currentDate);
    
            int step = days < 0 ? -1 : 1;
            int i = 0;
            int daysAbs = Math.abs(days);
            while (i < daysAbs) {
                calendar.add(Calendar.DATE, step);
                i++;
                if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
                        || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
    
                    i--;
                }
            }
    
            return calendar.getTime();
        }
    }

    结果:

    2019-08-14

    日历如下:

    2.  排除特殊工作日和休息日

      上面是按照所有的周一到周五休息、周六到周日工作来计算的,但是遇到国家法定节假日也需要进行特殊对待。

    package cn.xm.exam.utils;
    
    import java.text.ParseException;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    
    import org.apache.commons.lang.time.DateFormatUtils;
    import org.apache.commons.lang3.time.DateUtils;
    
    public class WorkDayCalculateUtils {
    
        /**
         * 特殊的工作日(星期六、日工作)
         */
        private static final List<String> SPECIAL_WORK_DAYS = new ArrayList<>();
    
        /**
         * 特殊的休息日(星期一到五休息)
         */
        private static final List<String> SPECIAL_REST_DAYS = new ArrayList<>();
    
        static {
            initSpecialDays();
        }
    
        public static Date getDate(Date currentDate, int days) {
            if (days == 0) {
                return currentDate;
            }
    
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(currentDate);
    
            int step = days < 0 ? -1 : 1;
            int i = 0;
            int daysAbs = Math.abs(days);
            while (i < daysAbs) {
                calendar.add(Calendar.DATE, step);
                i++;
                if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
                        || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
    
                    // 周六日如果上班就算1个工作日
                    if (!SPECIAL_WORK_DAYS.contains(DateFormatUtils.format(calendar.getTime(), "yyyy-MM-dd"))) {
                        i--;
                    }
                } else {
                    // 周1到周五休息就算1个休息日
                    if (SPECIAL_REST_DAYS.contains(DateFormatUtils.format(calendar.getTime(), "yyyy-MM-dd"))) {
                        i--;
                    }
                }
            }
    
            return calendar.getTime();
        }
    
        /**
         * 手工维护特殊日(因为是未知的,所以必须手工维护)
         */
        private static void initSpecialDays() {
            SPECIAL_WORK_DAYS.add("2019-09-29");
            SPECIAL_WORK_DAYS.add("2019-10-12");
    
            SPECIAL_REST_DAYS.add("2019-10-01");
            SPECIAL_REST_DAYS.add("2019-10-02");
            SPECIAL_REST_DAYS.add("2019-10-03");
            SPECIAL_REST_DAYS.add("2019-10-04");
            SPECIAL_REST_DAYS.add("2019-10-07");
        }
    
        public static void main(String[] args) throws ParseException {
            Date date = getDate(DateUtils.parseDate("2019-10-01", "yyyy-MM-dd"), 6);
            System.out.println(DateFormatUtils.format(date, "yyyy-MM-dd"));
        }
    }

    结果:

    2019-10-14

    日历:

       注意:上面的SPECIAL_WORK_DAYS、SPECIAL_REST_DAYS需要手工进行维护,这两个集合的数据来源可以的properties配置文件、xml文件或者数据库,建议采用properties配置文件进行配置,之后读取配置文件进行字符串切割。

  • 相关阅读:
    《CLR Via C# 第3版》笔记之(十四) 泛型高级
    《CLR Via C# 第3版》笔记之(十三) 泛型基础
    AOP学习基于Emit和Attribute的简单AOP实现
    《CLR Via C# 第3版》笔记之(十五) 接口
    C# 连接Oracle(利用ODP.net,不安装oracle客户端)
    《CLR Via C# 第3版》笔记之(十七) 线程基础
    C#直接读取磁盘文件(类似linux的Direct IO模式)
    《CLR Via C# 第3版》笔记之(十六) 字符串
    [置顶] C#中通过调用webService获取上网IP地址的区域的方法
    Android中Socket通讯类
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/11398698.html
Copyright © 2011-2022 走看看