博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java获取n个工作日后的日期, 排除周末和节假日(顺延)
阅读量:6253 次
发布时间:2019-06-22

本文共 10153 字,大约阅读时间需要 33 分钟。

一.说在前面

需求:

  工作需要获取n个工作日后的日期, 需要排除weekend和holiday, holiday存在数据库中, 存入的形式是一个节日有起始日期和截止日期(以下文中有关于节假日的表截图).

思路:

  大致为: 根据指定日期获取它tomorrow的日期, 判断tomorrow是否是周末和节假日, 如果不是则将tomorrow赋给today继续循环, 循环n次, 返回的today即是目标结果.

  1.查询数据库中的holiday, 存入list(需要注意的是, holiday记录里startTime和endTime颠倒的脏数据要剔除, startTime在endTime后面的记录显然是脏数据)

  2.判断today是否是周末

  3.判断today是否是节假日

  4.获取tomorrow的日期, 判断是否是weekendholiday, 如果不是则将tomorrow赋给today继续循环, 循环n次, 返回today

  (这里的today是指指定日期. 如:获取今天以后第10个工作日的日期 今天的日期就是指定日期).

工具类如何使用?

  使用方法见博文末尾说明.

二.以下为测试代码(测试时日期为2018-08-28):

package dong.test;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import java.util.List;/** * Created by liangyadong on 2018/8/28 0028. */public class HolidayTest {    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");    public static void main(String[] args) throws ParseException {        //查询数据库中holiday,遍历存入list(表中每条记录存放的是假期的起止日期,遍历每条结果,并将其中的每一天都存入holiday的list中),以下为模拟假期        List holidayList = new ArrayList();        holidayList.add("2018-08-29");        holidayList.add("2018-08-30");        holidayList.add("2018-10-01");        holidayList.add("2018-10-02");        holidayList.add("2018-10-03");        holidayList.add("2018-10-04");        holidayList.add("2018-10-05");        holidayList.add("2018-10-06");        holidayList.add("2018-10-07");        //获取计划激活日期        Date scheduleActiveDate = getScheduleActiveDate(holidayList);        System.out.println("10个工作日后,即计划激活日期为::" + sdf.format(scheduleActiveDate));    }    //获取计划激活日期    public static Date getScheduleActiveDate(List
list) throws ParseException {// java.sql.Date currentDate = new java.sql.Date(System.currentTimeMillis());//获取当前日期2018-08-26 Date today = new Date();//Mon Aug 27 00:09:29 CST 2018 Date tomorrow = null; int delay = 1; int num = 10;//根据需要设置,这个值就是业务需要的n个工作日 while(delay <= num){ tomorrow = getTomorrow(today); //当前日期+1即tomorrow,判断是否是节假日,同时要判断是否是周末,都不是则将scheduleActiveDate日期+1,直到循环num次即可 if(!isWeekend(sdf.format(tomorrow)) && !isHoliday(sdf.format(tomorrow),list)){ delay++; today = tomorrow; } else if (isWeekend(sdf.format(tomorrow))){// tomorrow = getTomorrow(tomorrow); today = tomorrow; System.out.println(sdf.format(tomorrow) + "::是周末"); } else if (isHoliday(sdf.format(tomorrow),list)){// tomorrow = getTomorrow(tomorrow); today = tomorrow; System.out.println(sdf.format(tomorrow) + "::是节假日"); } } System.out.println("10个工作日后,即计划激活日期为::" + sdf.format(today)); return today; } /** * 获取明天的日期 * * @param date * @return */ public static Date getTomorrow(Date date){ Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DAY_OF_MONTH, +1); date = calendar.getTime(); return date; } /** * 判断是否是weekend * * @param sdate * @return * @throws ParseException */ public static boolean isWeekend(String sdate) throws ParseException { Date date = sdf.parse(sdate); Calendar cal = Calendar.getInstance(); cal.setTime(date); if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){ return true; } else{ return false; } } /** * 判断是否是holiday * * @param sdate * @param list * @return * @throws ParseException */ public static boolean isHoliday(String sdate, List
list) throws ParseException { if(list.size() > 0){ for(int i = 0; i < list.size(); i++){ if(sdate.equals(list.get(i))){ return true; } } } return false; }}

输出main方法的执行结果:

2018-08-29::是节假日2018-08-30::是节假日2018-09-01::是周末2018-09-02::是周末2018-09-08::是周末2018-09-09::是周末10个工作日后,即计划激活日期为::2018-09-1310个工作日后,即计划激活日期为::2018-09-13

查看上面打印结果符合预期, 下面则是应用的说明.

三.应用

 1.首先看一下我数据库中存放的holiday, 每一个节日都是一个范围(有开始日期和结束日期)

 

2.从数据库中查询holiday结果集, 遍历结果集将每一天holiday存到holidayList中:

2.1 serviceImpl:

//查询holiday列表public List getHolidayList(){    //存放holiday的每一天    List holidayList = new ArrayList();    List
list = customerManageDao.getHolidayList(); //遍历holidayList if(list!=null&&list.size()>0){ for(HolidayInfoEntity holidayInfoEntity : list){ Date startTime = holidayInfoEntity.getStartTime(); Date endTime = holidayInfoEntity.getEndTime(); SimpleDateFormat sdf = PersDateUtils.getSdf(PersDateUtils.FORMAT_DATE_SPLIT); String sstartTime = sdf.format(startTime); String sendTime = sdf.format(endTime); Date tomorrow = HolidayUtils.getTomorrow(startTime); if(!sstartTime.equals(sendTime)){ holidayList.add(sstartTime); while(!sdf.format(tomorrow).equals(sendTime)){ tomorrow = HolidayUtils.getTomorrow(startTime); holidayList.add(sdf.format(tomorrow)); startTime = tomorrow; } }else{ holidayList.add(sstartTime); } } } return holidayList;}

2.2 daoImpl:(在这一步筛选符合逻辑的holiday, 即startTime小于endTime的)

//获取holiday列表@Overridepublic List getHolidayList() {    StringBuilder hql = new StringBuilder(" from HolidayInfoEntity h where h.startTime <= h.endTime ");    String hqlQuery = hql.toString();    Query query = getSession().createQuery(hqlQuery);    List
list = query.list(); return list;}

2.3 debug查看查询到的节假日:

3.调用HolidayUtils中的getScheduleActiveDate传入正确的参数, 返回值即是排除节假日和周末后的指定n个工作日后的日期.(HolidayUtils如下)

 

=====================傲娇的分割线: 封装到工具类内方便直接调用=====================

HolidayUtils.java

package com.ppms.utils;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.List;/** * Created by liangyadong on 2018/8/28 0028. */public class HolidayUtils {    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");    /**     * 获取计划激活日期     * @param today opening date     * @param list holidayList     * @param num num个工作日后     * @return     * @throws ParseException     */    public static Date getScheduleActiveDate(Date today, List
list, int num) throws ParseException { Date tomorrow = null; int delay = 1; while(delay <= num){ tomorrow = getTomorrow(today); //当前日期+1,判断是否是节假日,不是的同时要判断是否是周末,都不是则scheduleActiveDate日期+1 if(!isWeekend(sdf.format(tomorrow)) && !isHoliday(sdf.format(tomorrow),list)){ delay++; today = tomorrow; } else if (isWeekend(sdf.format(tomorrow))){ today = tomorrow; } else if (isHoliday(sdf.format(tomorrow),list)){ today = tomorrow; } } return today; } /** * 获取tomorrow的日期 * * @param date * @return */ public static Date getTomorrow(Date date){ Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DAY_OF_MONTH, +1); date = calendar.getTime(); return date; } /** * 判断是否是weekend * * @param sdate * @return * @throws ParseException */ public static boolean isWeekend(String sdate) throws ParseException { Date date = sdf.parse(sdate); Calendar cal = Calendar.getInstance(); cal.setTime(date); if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){ return true; } else{ return false; } } /** * 判断是否是holiday * * @param sdate * @param list * @return * @throws ParseException */ public static boolean isHoliday(String sdate, List
list) throws ParseException { if(list.size() > 0){ for(int i = 0; i < list.size(); i++){ if(sdate.equals(list.get(i))){ return true; } } } return false; }}

PersDateUtils.java

package com.ppms.utils;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;/** * Created by yadongliang on 2018/7/2 0002. */public class PersDateUtils {    public static final String FORMAT_DATE_SPLIT = "yyyy-MM-dd";    public static final String FORMAT_DATE_NONE = "yyyyMMdd";    public static final String FORMAT_DATE_TIME = "yyyy-MM-dd HH:mm:ss:SSS";    public static final String FORMAT_FULL_DATE_TIME = "yyyyMMddHHmmssSSS";    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";    //获取指定格式    public static SimpleDateFormat getSdf(String pattern) {        return new SimpleDateFormat(pattern);    }    //获取系统当前时间    public static Date getDate() {        return new Date();    }    //获取当前日历    public static Calendar getCalendar() {        return Calendar.getInstance();    }    //获取指定格式的日期sDate    public static String getPatternDate(String pattern, Date date){        return getSdf(pattern).format(date);    }    //字符串转日期    public static Date str2Date(String str, SimpleDateFormat sdf) {        if (null == str || "".equals(str)) {            return null;        }        Date date = null;        try {            date = sdf.parse(str);            return date;        } catch (ParseException e) {            e.printStackTrace();        }        return null;    }}

 

使用说明:

  将HolidayUtils.java和PersDateUtils.java拷贝到自己项目中, 调用HolidayUtils中的getScheduleActiveDate()传入正确的参数, 返回值即是目标日期.

  Date getScheduleActiveDate(Date today, List<String> list, int num)

  参数说明:

    Date today: 指定日期 格式 yyyy-MM-dd

    List<String> list: 业务内定义的节假日的list 格式 yyyy-MM-dd

    int num: 指定天数

 

  例如:

    获取今天(2018-08-28)起 10天后的日期, 节假日从数据库中查询并存入到holidayList中, 标红的参数传入方法中即可.

 

思路基本上这样, 逻辑不是很严谨, 如果bug, 欢迎讨论.

 

转载地址:http://giysa.baihongyu.com/

你可能感兴趣的文章
mysql in 查询改成_MySQL not in嵌套查询改写成外连接方式
查看>>
mysql community安装_MySQL Community Server 5.7安装详细步骤
查看>>
python处理多行字符串_python多行字符串
查看>>
java冒泡排序_用java写个冒泡排序?
查看>>
linux 开发java_做开发环境的操作系统是 Linux 好还是 Windows 好?
查看>>
java正文提取_Java网页正文提取工具
查看>>
blocked java_使用jstack排查多线程死锁、阻塞
查看>>
centos7 nohup无法保持_CentOS 不间断会话(ssh关闭后如何保证程序继续运行)(nohup和screen)...
查看>>
显示图片java代码_用于显示下载或是显示图片的一段代码
查看>>
java scrip_js java scrip基本语法
查看>>
java 加上天数_java日期时间加上天数 | 学步园
查看>>
java 爬楼梯算法_9.1 爬楼梯
查看>>
java多态 动态绑定_Java JVM 多态(动态绑定)
查看>>
jpa 去重_JPA 查询Distinct Join条件示例
查看>>
mysql date 索引性能_【转】MYSQL数据库时间字段INT,TIMESTAMP,DATETIME性能效率比较
查看>>
java 加密解密算法_用JAVA设计一个简单的加密、解密算法,用该算法来实现对数据的加密、解密...
查看>>
java 窗口最小化_Java使窗口最小化为图标
查看>>
hessian java php_hessian在PHP中的使用
查看>>
虚幻4能用java吗_如果用虚幻四引擎开发我的世界而非java 它会比现在取得更好的成绩吗?...
查看>>
JAVA常见告警怎么解决_JAVA 线上故障排查全套路
查看>>