java获取n个工作日后的日期, 排除周末和节假日(顺延)
一.写在前面
需求描述
工作需要获取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)
- 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<String> 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<String> 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-13
- 10个工作日后,即计划激活日期为::2018-09-13
查看上面打印结果符合预期, 下面则是应用的说明.
三.应用
1.首先看一下我数据库中存放的holiday, 每一个节日都是一个范围(有开始日期和结束日期)
2.从数据库中查询holiday结果集, 遍历结果集将每一天holiday存到holidayList中
2.1 serviceImpl:
- //查询holiday列表
- public List getHolidayList(){
- //存放holiday的每一天
- List holidayList = new ArrayList();
- List<HolidayInfoEntity> 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列表
- @Override
- public List getHolidayList() {
- StringBuilder hql = new StringBuilder(" from HolidayInfoEntity h where h.startTime <= h.endTime ");
- String hqlQuery = hql.toString();
- Query query = getSession().createQuery(hqlQuery);
- List<HolidayInfoEntity> 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<String> 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<String> 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)起 天后的日期, 节假日从数据库中查询并存入到holidayList中, 标红的参数传入方法中即可.
思路基本上这样, 逻辑不是很严谨, 如果有bug, 欢迎留言讨论~
java获取n个工作日后的日期, 排除周末和节假日(顺延)的更多相关文章
- java获取当前年份、月份和日期字符串等
Java获取当前年份.月份和日期是通过Calendar类的实例对象来获取的. 首先创建一个Calendar类的实例对象,Calendar类属于java.util包. Calendar calendar ...
- N个工作日后的日期
这里对特殊日期采用了模拟的方式,在实际开发中当然这些数据是从数据库中读取,调用方法时 只需传入开始时间(一般当前) 和N(代表N个工作日) /// <summary> /// 获取时间 / ...
- java获取上周任意一天的日期
/** * 获取上周周几的日期,默认一周从周一开始 * @param dayOfWeek * @param weekOffset * @return */ public static Date get ...
- JAVA获取当前年份,月份、日期、小时、分钟、秒等
import java.util.Calendar; public class Main { public static void main(String[] args) { Calendar cal ...
- JAVA获取当前日期指定天数之后的日期
/** * 获取day天之后的日期 * @param day 天数 * @return */ public static String getDate(int day){ Calendar calen ...
- java获取一段字符串里符合日期的正则表达式的字符串
import java.util.regex.Matcher; import java.util.regex.Pattern; public class Test3 { public static v ...
- python 递归计算若干工作日后的日期
import datetime # 根据第一次计算出来的休息日数,计算还需要的工作日数.(递归调用) def get_next_date(self, start_date, weekend_days) ...
- 【原创】java 获取十个工作日之前或之后的日期(算当天)-完美解决-费元星
[原创]java 获取十个工作日之后的日期(算当天)-完美解决-费元星(仅考虑星期六星期天) /** * * 根据开始日期 ,需要的工作日天数 ,计算工作截止日期,并返回截止日期 * @param s ...
- java获取当天,前天,明天,本周,本月,本年的开始日期时间和结束日期时间
package demoone; import java.sql.Timestamp; import java.text.ParseException; import java.text.Simple ...
随机推荐
- C#窗体读取EXCEL存入SQL数据库
windows窗体上放了一个Textbox1,2个按钮button1和button2~按button1选择excel文件~按button2进行相关处理 Code Snippet private vo ...
- Spring Boot集成MyBatis开发Web项目
1.Maven构建Spring Boot 创建Maven Web工程,引入spring-boot-starter-parent依赖 <project xmlns="http://mav ...
- 图形数据库 Neo4j 开发实战
https://www.ibm.com/developerworks/cn/java/j-lo-neo4j/ Neo4j 是一个高性能的 NoSQL 图形数据库.Neo4j 使用图(graph)相关的 ...
- go-ethereum
如果要深入了解go-ethereum项目的实现与机制,看源代码是必不可少的.今天这篇博客就简单介绍一下如何在本地搭建项目的开发环境. GO语言环境搭建 以win8为例,访问地址https://gola ...
- 【Python】将对象存成json文件及从json取出对象
常用代码,单拎出来以备查. 对象存json文件: import json obj={'name':'张有财','age':39,'arr':[2,34,5,6,7,88,'李有钱']} with op ...
- 【iOS开发】如何用 Swift 语言进行LBS应用的开发?
本文分为三部分,第一部分详解用Swift语言开发LBS应用,并给出完整的示例与源代码:第二部分介绍如何申请LBS密钥,第三部分是综合示例查看,扫描二维码即可查看示例demo. 第一部分 使用Swift ...
- Android 之 WebView开发问题及优化
WebView 在现在的项目中使用的频率应该还是非常高的,WebView 主要用来加载一些容易改变的频繁交互的应用App.目前 HTML5 是一种趋势.在开发中会遇到一些开发问题及优化问题,如下所记. ...
- Django模板过滤器详解
Django 模板过滤器也是我们在以后基于 Django 网站开发过程中会经常遇到的,如显示格式的转换.判断处理等.以下是 Django 过滤器列表,希望对为大家的开发带来一些方便. 一.形式:小写 ...
- 微信 js api[转]
rainbow661314 微信api /**! * 微信内置浏览器的Javascript API,功能包括: * * 1.分享到微信朋友圈 * 2.分享给微信好友 * 3.分享到腾讯微博 * 4.新 ...
- linux 新进程的创建
慕课18原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.背景知识: 1. ...