一.写在前面

需求描述

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

思路解析

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

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

  2.判断today是否是周末

  3.判断today是否是节假日

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

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

工具类如何使用?

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

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

  1. package dong.test;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.ArrayList;
  6. import java.util.Calendar;
  7. import java.util.Date;
  8. import java.util.List;
  9.  
  10. /**
  11. * Created by liangyadong on 2018/8/28 0028.
  12. */
  13. public class HolidayTest {
  14.  
  15. private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  16.  
  17. public static void main(String[] args) throws ParseException {
  18. //查询数据库中holiday,遍历存入list(表中每条记录存放的是假期的起止日期,遍历每条结果,并将其中的每一天都存入holiday的list中),以下为模拟假期
  19. List holidayList = new ArrayList();
  20. holidayList.add("2018-08-29");
  21. holidayList.add("2018-08-30");
  22. holidayList.add("2018-10-01");
  23. holidayList.add("2018-10-02");
  24. holidayList.add("2018-10-03");
  25. holidayList.add("2018-10-04");
  26. holidayList.add("2018-10-05");
  27. holidayList.add("2018-10-06");
  28. holidayList.add("2018-10-07");
  29.  
  30. //获取计划激活日期
  31. Date scheduleActiveDate = getScheduleActiveDate(holidayList);
  32. System.out.println("10个工作日后,即计划激活日期为::" + sdf.format(scheduleActiveDate));
  33. }
  34.  
  35. //获取计划激活日期
  36. public static Date getScheduleActiveDate(List<String> list) throws ParseException {
  37. // java.sql.Date currentDate = new java.sql.Date(System.currentTimeMillis());//获取当前日期2018-08-26
  38. Date today = new Date();//Mon Aug 27 00:09:29 CST 2018
  39. Date tomorrow = null;
  40. int delay = 1;
  41. int num = 10;//根据需要设置,这个值就是业务需要的n个工作日
  42. while(delay <= num){
  43. tomorrow = getTomorrow(today);
  44. //当前日期+1即tomorrow,判断是否是节假日,同时要判断是否是周末,都不是则将scheduleActiveDate日期+1,直到循环num次即可
  45. if(!isWeekend(sdf.format(tomorrow)) && !isHoliday(sdf.format(tomorrow),list)){
  46. delay++;
  47. today = tomorrow;
  48. } else if (isWeekend(sdf.format(tomorrow))){
  49. // tomorrow = getTomorrow(tomorrow);
  50. today = tomorrow;
  51. System.out.println(sdf.format(tomorrow) + "::是周末");
  52. } else if (isHoliday(sdf.format(tomorrow),list)){
  53. // tomorrow = getTomorrow(tomorrow);
  54. today = tomorrow;
  55. System.out.println(sdf.format(tomorrow) + "::是节假日");
  56. }
  57. }
  58. System.out.println("10个工作日后,即计划激活日期为::" + sdf.format(today));
  59. return today;
  60. }
  61.  
  62. /**
  63. * 获取明天的日期
  64. *
  65. * @param date
  66. * @return
  67. */
  68. public static Date getTomorrow(Date date){
  69. Calendar calendar = Calendar.getInstance();
  70. calendar.setTime(date);
  71. calendar.add(Calendar.DAY_OF_MONTH, +1);
  72. date = calendar.getTime();
  73. return date;
  74. }
  75.  
  76. /**
  77. * 判断是否是weekend
  78. *
  79. * @param sdate
  80. * @return
  81. * @throws ParseException
  82. */
  83. public static boolean isWeekend(String sdate) throws ParseException {
  84. Date date = sdf.parse(sdate);
  85. Calendar cal = Calendar.getInstance();
  86. cal.setTime(date);
  87. if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
  88. return true;
  89. } else{
  90. return false;
  91. }
  92.  
  93. }
  94.  
  95. /**
  96. * 判断是否是holiday
  97. *
  98. * @param sdate
  99. * @param list
  100. * @return
  101. * @throws ParseException
  102. */
  103. public static boolean isHoliday(String sdate, List<String> list) throws ParseException {
  104. if(list.size() > 0){
  105. for(int i = 0; i < list.size(); i++){
  106. if(sdate.equals(list.get(i))){
  107. return true;
  108. }
  109. }
  110. }
  111. return false;
  112. }
  113.  
  114. }

输出main方法的执行结果:

  1. 2018-08-29::是节假日
  2. 2018-08-30::是节假日
  3. 2018-09-01::是周末
  4. 2018-09-02::是周末
  5. 2018-09-08::是周末
  6. 2018-09-09::是周末
  7. 10个工作日后,即计划激活日期为::2018-09-13
  8. 10个工作日后,即计划激活日期为::2018-09-13

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

三.应用

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

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

2.1 serviceImpl:

  1. //查询holiday列表
  2. public List getHolidayList(){
  3. //存放holiday的每一天
  4. List holidayList = new ArrayList();
  5.  
  6. List<HolidayInfoEntity> list = customerManageDao.getHolidayList();
  7. //遍历holidayList
  8. if(list!=null&&list.size()>0){
  9. for(HolidayInfoEntity holidayInfoEntity : list){
  10. Date startTime = holidayInfoEntity.getStartTime();
  11. Date endTime = holidayInfoEntity.getEndTime();
  12.  
  13. SimpleDateFormat sdf = PersDateUtils.getSdf(PersDateUtils.FORMAT_DATE_SPLIT);
  14. String sstartTime = sdf.format(startTime);
  15. String sendTime = sdf.format(endTime);
  16.  
  17. Date tomorrow = HolidayUtils.getTomorrow(startTime);
  18. if(!sstartTime.equals(sendTime)){
  19. holidayList.add(sstartTime);
  20. while(!sdf.format(tomorrow).equals(sendTime)){
  21. tomorrow = HolidayUtils.getTomorrow(startTime);
  22. holidayList.add(sdf.format(tomorrow));
  23. startTime = tomorrow;
  24. }
  25. }else{
  26. holidayList.add(sstartTime);
  27. }
  28. }
  29. }
  30.  
  31. return holidayList;
  32. }

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

  1. //获取holiday列表
  2. @Override
  3. public List getHolidayList() {
  4. StringBuilder hql = new StringBuilder(" from HolidayInfoEntity h where h.startTime <= h.endTime ");
  5. String hqlQuery = hql.toString();
  6. Query query = getSession().createQuery(hqlQuery);
  7. List<HolidayInfoEntity> list = query.list();
  8. return list;
  9. }

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

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

代码备份

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

HolidayUtils.java

  1. package com.ppms.utils;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Calendar;
  6. import java.util.Date;
  7. import java.util.List;
  8.  
  9. /**
  10. * Created by liangyadong on 2018/8/28 0028.
  11. */
  12. public class HolidayUtils {
  13. private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  14. /**
  15. * 获取计划激活日期
  16. * @param today opening date
  17. * @param list holidayList
  18. * @param num num个工作日后
  19. * @return
  20. * @throws ParseException
  21. */
  22. public static Date getScheduleActiveDate(Date today, List<String> list, int num) throws ParseException {
  23. Date tomorrow = null;
  24. int delay = 1;
  25. while(delay <= num){
  26. tomorrow = getTomorrow(today);
  27. //当前日期+1,判断是否是节假日,不是的同时要判断是否是周末,都不是则scheduleActiveDate日期+1
  28. if(!isWeekend(sdf.format(tomorrow)) && !isHoliday(sdf.format(tomorrow),list)){
  29. delay++;
  30. today = tomorrow;
  31. } else if (isWeekend(sdf.format(tomorrow))){
  32. today = tomorrow;
  33. } else if (isHoliday(sdf.format(tomorrow),list)){
  34. today = tomorrow;
  35. }
  36. }
  37.  
  38. return today;
  39. }
  40.  
  41. /**
  42. * 获取tomorrow的日期
  43. *
  44. * @param date
  45. * @return
  46. */
  47. public static Date getTomorrow(Date date){
  48. Calendar calendar = Calendar.getInstance();
  49. calendar.setTime(date);
  50. calendar.add(Calendar.DAY_OF_MONTH, +1);
  51. date = calendar.getTime();
  52. return date;
  53. }
  54.  
  55. /**
  56. * 判断是否是weekend
  57. *
  58. * @param sdate
  59. * @return
  60. * @throws ParseException
  61. */
  62. public static boolean isWeekend(String sdate) throws ParseException {
  63. Date date = sdf.parse(sdate);
  64. Calendar cal = Calendar.getInstance();
  65. cal.setTime(date);
  66. if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
  67. return true;
  68. } else{
  69. return false;
  70. }
  71.  
  72. }
  73.  
  74. /**
  75. * 判断是否是holiday
  76. *
  77. * @param sdate
  78. * @param list
  79. * @return
  80. * @throws ParseException
  81. */
  82. public static boolean isHoliday(String sdate, List<String> list) throws ParseException {
  83. if(list.size() > 0){
  84. for(int i = 0; i < list.size(); i++){
  85. if(sdate.equals(list.get(i))){
  86. return true;
  87. }
  88. }
  89. }
  90. return false;
  91. }
  92. }

PersDateUtils.java

  1. package com.ppms.utils;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Calendar;
  6. import java.util.Date;
  7.  
  8. /**
  9. * Created by yadongliang on 2018/7/2 0002.
  10. */
  11. public class PersDateUtils {
  12.  
  13. public static final String FORMAT_DATE_SPLIT = "yyyy-MM-dd";
  14. public static final String FORMAT_DATE_NONE = "yyyyMMdd";
  15. public static final String FORMAT_DATE_TIME = "yyyy-MM-dd HH:mm:ss:SSS";
  16. public static final String FORMAT_FULL_DATE_TIME = "yyyyMMddHHmmssSSS";
  17. public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
  18.  
  19. //获取指定格式
  20. public static SimpleDateFormat getSdf(String pattern) {
  21. return new SimpleDateFormat(pattern);
  22. }
  23.  
  24. //获取系统当前时间
  25. public static Date getDate() {
  26. return new Date();
  27. }
  28.  
  29. //获取当前日历
  30. public static Calendar getCalendar() {
  31. return Calendar.getInstance();
  32. }
  33.  
  34. //获取指定格式的日期sDate
  35. public static String getPatternDate(String pattern, Date date){
  36. return getSdf(pattern).format(date);
  37. }
  38.  
  39. //字符串转日期
  40. public static Date str2Date(String str, SimpleDateFormat sdf) {
  41. if (null == str || "".equals(str)) {
  42. return null;
  43. }
  44. Date date = null;
  45. try {
  46. date = sdf.parse(str);
  47. return date;
  48. } catch (ParseException e) {
  49. e.printStackTrace();
  50. }
  51. return null;
  52. }
  53.  
  54. }

使用说明

  将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)起 天后的日期, 节假日从数据库中查询并存入到holidayList中, 标红的参数传入方法中即可.

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

java获取n个工作日后的日期, 排除周末和节假日(顺延)的更多相关文章

  1. java获取当前年份、月份和日期字符串等

    Java获取当前年份.月份和日期是通过Calendar类的实例对象来获取的. 首先创建一个Calendar类的实例对象,Calendar类属于java.util包. Calendar calendar ...

  2. N个工作日后的日期

    这里对特殊日期采用了模拟的方式,在实际开发中当然这些数据是从数据库中读取,调用方法时 只需传入开始时间(一般当前) 和N(代表N个工作日) /// <summary> /// 获取时间 / ...

  3. java获取上周任意一天的日期

    /** * 获取上周周几的日期,默认一周从周一开始 * @param dayOfWeek * @param weekOffset * @return */ public static Date get ...

  4. JAVA获取当前年份,月份、日期、小时、分钟、秒等

    import java.util.Calendar; public class Main { public static void main(String[] args) { Calendar cal ...

  5. JAVA获取当前日期指定天数之后的日期

    /** * 获取day天之后的日期 * @param day 天数 * @return */ public static String getDate(int day){ Calendar calen ...

  6. java获取一段字符串里符合日期的正则表达式的字符串

    import java.util.regex.Matcher; import java.util.regex.Pattern; public class Test3 { public static v ...

  7. python 递归计算若干工作日后的日期

    import datetime # 根据第一次计算出来的休息日数,计算还需要的工作日数.(递归调用) def get_next_date(self, start_date, weekend_days) ...

  8. 【原创】java 获取十个工作日之前或之后的日期(算当天)-完美解决-费元星

    [原创]java 获取十个工作日之后的日期(算当天)-完美解决-费元星(仅考虑星期六星期天) /** * * 根据开始日期 ,需要的工作日天数 ,计算工作截止日期,并返回截止日期 * @param s ...

  9. java获取当天,前天,明天,本周,本月,本年的开始日期时间和结束日期时间

    package demoone; import java.sql.Timestamp; import java.text.ParseException; import java.text.Simple ...

随机推荐

  1. C#窗体读取EXCEL存入SQL数据库

    windows窗体上放了一个Textbox1,2个按钮button1和button2~按button1选择excel文件~按button2进行相关处理 Code Snippet private  vo ...

  2. Spring Boot集成MyBatis开发Web项目

    1.Maven构建Spring Boot 创建Maven Web工程,引入spring-boot-starter-parent依赖 <project xmlns="http://mav ...

  3. 图形数据库 Neo4j 开发实战

    https://www.ibm.com/developerworks/cn/java/j-lo-neo4j/ Neo4j 是一个高性能的 NoSQL 图形数据库.Neo4j 使用图(graph)相关的 ...

  4. go-ethereum

    如果要深入了解go-ethereum项目的实现与机制,看源代码是必不可少的.今天这篇博客就简单介绍一下如何在本地搭建项目的开发环境. GO语言环境搭建 以win8为例,访问地址https://gola ...

  5. 【Python】将对象存成json文件及从json取出对象

    常用代码,单拎出来以备查. 对象存json文件: import json obj={'name':'张有财','age':39,'arr':[2,34,5,6,7,88,'李有钱']} with op ...

  6. 【iOS开发】如何用 Swift 语言进行LBS应用的开发?

    本文分为三部分,第一部分详解用Swift语言开发LBS应用,并给出完整的示例与源代码:第二部分介绍如何申请LBS密钥,第三部分是综合示例查看,扫描二维码即可查看示例demo. 第一部分 使用Swift ...

  7. Android 之 WebView开发问题及优化

    WebView 在现在的项目中使用的频率应该还是非常高的,WebView 主要用来加载一些容易改变的频繁交互的应用App.目前 HTML5 是一种趋势.在开发中会遇到一些开发问题及优化问题,如下所记. ...

  8. Django模板过滤器详解

    Django 模板过滤器也是我们在以后基于 Django 网站开发过程中会经常遇到的,如显示格式的转换.判断处理等.以下是 Django 过滤器列表,希望对为大家的开发带来一些方便. 一.形式:小写 ...

  9. 微信 js api[转]

    rainbow661314 微信api /**! * 微信内置浏览器的Javascript API,功能包括: * * 1.分享到微信朋友圈 * 2.分享给微信好友 * 3.分享到腾讯微博 * 4.新 ...

  10. linux 新进程的创建

    慕课18原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.背景知识: 1. ...