项目背景
业务提了一个这样的需求,在输入开始日期和工作日,后台自动计算出一个完成日期。要求以工作日计算,需要跳过法定节假期和调休日。
参数说明
beginDay: 为前端传入的开始日期
day:为前端传入的工作日
holiday:为法定节假期 可改为从数据库获取
extraWorkDay: 为需要上班的调休日 可改为从数据库获取
测试代码如下
package com.example.demo;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @auther Fanseline
* @date 2023/4/6
*/
public class Test {
public static void main(String[] args) throws Exception {
//测试数据 开始日期
String beginDay= "2023-04-28";
//需要完成的天数 即工作日
int day =10;
//存当前年份和明年的节假日期 可改为从数据库获取,建议手动维护节假日期
List<String> holiday = new ArrayList<>();
holiday.add("2023-04-29");//休息
holiday.add("2023-04-30");
holiday.add("2023-05-01");
holiday.add("2023-05-02");
holiday.add("2023-05-03");
//存当前年份和明年的调班日期 可改为从数据库获取,建议手动维护日期
List<String> extraWorkDay = new ArrayList<>();
extraWorkDay.add("2023-04-23");//上班
extraWorkDay.add("2023-05-06");//上班
//
// int count = day+1; //加1方便返回结束日期(计算后的时间理应不包含当天工作日)
while (0 != day) {
String ifdate = dateAddOne(beginDay);
if (isWorkingDay(ifdate, holiday,extraWorkDay)) {
day = day - 1;
}
beginDay = ifdate;
}
System.out.println("预期完成日期:"+beginDay+"===========================");
}
//上班日返回true
public static Boolean isWorkingDay(String beginDay, List<String> holiday, List<String> extraWorkDay) throws Exception {
//是否加班日
if (extraWorkDay.contains(beginDay)) {
return true;
}
//是否节假日
if (holiday.contains(beginDay)) {
return false;
}
//跳过星期6和星期天
String week = getWeek(beginDay);
if ("Saturday".equals(week) || "Sunday".equals(week)) {
return false;
}
return true;
}
// 计算星期几
public static String getWeek(String dateParm) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Calendar calendar = Calendar.getInstance();
try {
Date date = dateFormat.parse(dateParm);
calendar.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
String[] weeks = new String[]{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int weekIndex = calendar.get(Calendar.DAY_OF_WEEK) - 1;
if (weekIndex < 0) {
weekIndex = 0;
}
return weeks[weekIndex];
}
//日期加+1天
public static String dateAddOne(String param) throws ParseException {
Calendar calendar = new GregorianCalendar();
calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(param));
calendar.add(calendar.DATE, 1);
Date date = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
}
运行结果
Connected to the target VM, address: '127.0.0.1:55528', transport: 'socket'
预期完成日期:2023-05-17===========================
Disconnected from the target VM, address: '127.0.0.1:55528', transport: 'socket'
Process finished with exit code 0