Java 根据开始日期和结束日期,获取日期之间的工作日,去除了周末和法定节假日
程序员文章站
2022-05-16 21:30:34
...
输出结果:
public static void main(String[] args) {
String sd = “2021-02-01”;
String ed = “2021-02-28”;
List list = getWorkDays(sd,ed);
for (String date: list) {
System.out.println(date);
}
}
/**
* 此方法计算两个日期的真实工作日(除周末和法定节假日)
* @param startDate(起始日期),EndDate(结束时间)
* @return list(去除周末和法定节假日后的日期字符串)
*/
public static List<String> getWorkDays(String startDate,String EndDate){
SimpleDateFormat simp = new SimpleDateFormat("yyyy-MM-dd");
Date startTime = null;
Date endTime = null;
try {
startTime = simp.parse(startDate);
endTime = simp.parse(EndDate);
} catch (ParseException e) {
e.printStackTrace();
}
List<Date> datesBetweenTwoDate = getDatesBetweenTwoDate(startTime, endTime);
List<String> list = new ArrayList<>();
for (Date date : datesBetweenTwoDate) {
String format = simp.format(date);
list.add(format);
}
return list;
}
/**
* 判断一个日期是不是周末.
* @param calendar(要判断的日期)
* @return Boolean(返回true为是周末)
*/
private static boolean isWeekend(Calendar calendar){
//判断是星期几
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == 1 || dayOfWeek == 7){
if(isWeekendWorkDays(calendar)){
return false;
}else{
return true;
}
}
return false;
}
/**
* 一个日历是不是法定节假日
* WorkDayPlusConfig.properties为配置文件,其中存放了法定节假日期,格式为:holiday=2018-10-1,...,..
* @param calendar (要判断的日期)
* @return Boolean(返回true为是法定节假日)
*/
private static boolean isHoliday(Calendar calendar){
String pattern = "yyyy-MM-dd";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
String dateString = simpleDateFormat.format(calendar.getTime());
//节假日 这个可能不同地区,不同年份 都有可能不一样,所以需要有个地方配置, 可以放数据库, 配置文件,环境变量 等等地方
//TODO 可以放到数据库中
String holidays = "2020-01-01,2020-01-24,2020-01-25,2020-01-26,2020-01-27,2020-01-28,2020-01-29,2020-01-30,2020-01-31," +
"2020-02-01,2020-02-02," +
"2020-04-04,2020-04-05,2020-04-06," +
"2020-05-01,2020-05-02,2020-05-03,2020-05-04,2020-05-05," +
"2020-06-25,2020-06-26,2020-06-27," +
"2020-10-01,2020-10-02,2020-10-03,2020-10-04,2020-10-05,2020-10-06,2020-10-07,2020-10-08," +
"2021-01-01,2021-01-02,2021-01-03,2021-02-11,2021-02-12," +
"2021-02-13,2021-02-14,2021-02-15,2021-02-16,2021-02-17," +
"2021-04-03,2021-04-04,2021-04-05,2021-05-01,2021-05-02," +
"2021-05-03,2021-05-04,2021-05-05,2021-06-12,2021-06-13," +
"2021-06-14,2021-09-19,2021-09-20,2021-09-21," +
"2021-10-01,2021-10-02,2021-10-03,2021-10-04,2021-10-05,2021-10-06,2021-10-07";
String[] holidayArray = holidays.split(",");
boolean isHoliday = ArrayUtils.contains(holidayArray, dateString);
return isHoliday;
}
/**
* 一个日历是不是法定要工作的周末
*WorkDayPlusConfig.properties为配置文件,其中存放了法定节假日期,格式为:WeekendWorkDays=2018-9-29,...,..
* @param calendar (要判断的日期)
* @return Boolean(返回true为确实是要工作的周末)
*/
private static boolean isWeekendWorkDays(Calendar calendar){
String pattern = "yyyy-MM-dd";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
String dateString = simpleDateFormat.format(calendar.getTime());
//节假日 这个可能不同地区,不同年份 都有可能不一样,所以需要有个地方配置, 可以放数据库, 配置文件,环境变量 等等地方
//TODO 可以放到数据库中,节假日调的工作日,周末工作日
String weekendWorkDays = "2020-01-19,2020-04-26,2020-05-09,2020-06-28,2020-09-27,2020-10-10,2021-02-07,2021-02-20,2021-04-25,2021-05-08,2021-09-18,2021-09-26,2021-10-09";
String[] weekendWorkDaysArray = weekendWorkDays.split(",");
boolean isWeekendWorkDays = ArrayUtils.contains(weekendWorkDaysArray, dateString);
return isWeekendWorkDays;
}
/**
* 根据开始时间和结束时间返回时间段内的时间集合
*
* @param beginDate
* @param endDate
* @return List
*/
public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
Date workStartTime = endDate;//结束时间那天的上班时间
List<Date> lDate = new ArrayList<Date>();
Calendar cal = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
cal.setTime(beginDate);
boolean bContinue = true;
while (bContinue) {
//判断是否到最后一天,结束循环
if (endDate.after(cal.getTime()) || DateUtils.isSameDay(endDate, cal.getTime())) {
if (!isWeekend(cal) && !isHoliday(cal)){
lDate.add(cal.getTime());
}
} else {
break;
}
// 日期加一
cal.add(Calendar.DAY_OF_MONTH, 1);
}
if((!(DateUtils.isSameDay(beginDate, endDate)))&&endDate.after(workStartTime)&&endDate.after(beginDate)){//日期不是同一天且在当天工作时间(结束算起)之后
lDate.add(endDate);// 把结束时间加入集合
}
return lDate;
}