由于工作需要:加减工作日得到具体的日期和计算两个日期之间工作日两种需求(当然参考了其他作者的内容,在这里自己做了重新处理):
- 首先手动录入今年或最近几年的工作日和调休日,先在excel中录入,格式如下(写END为了补齐第三列,后面加载时候要用):
节假日 | 法定调休工作日 | END |
2017/1/28 | END | |
2017/1/29 | 2017/1/14 | END |
2017/1/30 | 2017/1/15 | END |
2. 把除了表头“节假日”“法定调休工作日”“END”的其他三列拷贝到一个新的sheet中;
3. 点击excel中的另存为:文本文件(制表符分割)也就是.txt文件;
4. 加载生成的.txt文件;
5. 加载一次后存入static静态代码块中;
6. 构建了getWorkDayNum(String dateStartStr,String dateEndStr)
方法和getWorkDay(String dateStartStr,int n)
方法分别获取两个日期之间的工作日和距离dateStartStr有n个工作日的日期,如果n为负数则再加判断即可,后面也写了;
7. 具体代码如下:(当然要在启动的时候加载读取txt的方法,在grails中是这样写的,如HolidayWorkdayUtil.initialize(grailsApplication.config.workday.holiday.file as String)
)
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
* 根据读取配置的txt判断是否为法定节假日,及法定工作日
* @author
*/
public class HolidayWorkdayUtil {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
private static List<String> holidays = new ArrayList<String>();
private static List<String> workdays = new ArrayList<String>();
/**
* 获取剩余的工作日天数
* @param date
* @return
* @throws ParseException
*/
public int getWorkDayNum(String dateStartStr,String dateEndStr) throws ParseException{
Date now=sdf.parse(dateStartStr);
boolean flag = true;
int count=0;
String today="";
Date da=sdf.parse(dateEndStr);
if(da.getTime()>=now.getTime()){
//System.out.println(holidays);
// System.out.println(workdays);
Calendar c = Calendar.getInstance();
for(int i=0;i<=3650;i++){
c.setTime(now);
c.set(Calendar.DATE, c.get(Calendar.DATE) + i);
int dateType = getDateType(c);
today = sdf.format(c.getTime());
//System.out.println("date..."+today);
//如果文件不存在当前日期。判断是否周六日
if(dateType==0){
if(c.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY||
c.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY){
flag = false;
}else{
flag=true;
}
}else{//如果存在当前日期,根据返回的类型判断
if(dateType==1){//节假日
flag = false;
}else if(dateType==2){//工作日
flag = true;
}
}
// System.out.println(today+"是:"+(flag==true?"工作日":"节假日"));
if(flag){
count++;
}
// System.out.println(count);
if(today.equals(dateEndStr) || today==dateEndStr){
break;
}
}
}
return count-1;
}
/**
* 判断当天是否是工作日 (工作日:true;节假日:false)
* @param filePath
* @return
* @throws ParseException
*/
public String getWorkDay(String dateStartStr,int n) throws ParseException{
boolean flag = true;
int count=0;
String today="";
//System.out.println(holidays);
//System.out.println(workdays);
Date now=sdf.parse(dateStartStr);
Calendar c = Calendar.getInstance();
for(int i=0;i<=3650;i++){//这里是一天一天的加,如果有更好的也可以
c.setTime(now);
c.set(Calendar.DATE, c.get(Calendar.DATE) + i);
int dateType = getDateType(c);
today = sdf.format(c.getTime());
//System.out.println("date..."+today);
//如果文件不存在当前日期。判断是否周六日
if(dateType==0){
if(c.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY||
c.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY){
flag = false;
}else{
flag=true;
}
}else{//如果存在当前日期,根据返回的类型判断
if(dateType==1){//节假日
flag = false;
}else if(dateType==2){//工作日
flag = true;
}
}
// System.out.println(today+"是:"+(flag==true?"工作日":"节假日"));
if(flag){
count++;
}
// System.out.println(count);
if(count==(n+1)){
break;
}
}
return today;
}
/**
* 根据判断当前时间是否是节假日还是工作日 (txt中不存在当前日期:0;节假日:1;工作日:2)
* 如果当前日期在txt中的节假日和工作日都写了,默认的工作日
* @return
*/
private int getDateType(Calendar c){
int type = 0;
String today = sdf.format(c.getTime());
if(holidays.size()>0){
for(String holiday:holidays){
if(holiday.equals(today)){
type = 1;
break;
}
}
}
if(workdays.size()>0){
for(String workday:workdays){
if(workday.equals(today)){
type = 2;
}
}
}
return type;
}
/**
* 读取excel中的节假日和工作日,同时统一日期格式为2017-01-01
*/
public static void initialize(String filePath){
if(filePath==null||"".equals(filePath)){
return ;
}
Scanner in = null;
try {
in = new Scanner(new File(filePath));
String result1 = "";
while (in.hasNextLine()) {
result1 = in.nextLine() ;
String[] strArray=result1.split("\t");
if(strArray==null||strArray.length==0){
return;
}
//获取第一列数据-节假日
String analyStartDate="";
String startDateStr="";
try{
analyStartDate=strArray[0].trim();
if(analyStartDate=="" || analyStartDate.equals("") || "\\".contains(analyStartDate)){
analyStartDate="";
}else{
Pattern pa = Pattern.compile("\\D+");
String[] numbers = pa.split(analyStartDate);
int a=0;
for(String number:numbers){
if(null!=number && !"".equals(number)){
if(a>0 && a<3){
int i = Integer.parseInt(number);
if(i<10 && !number.contains("0")){
startDateStr=startDateStr+"-"+"0"+number;
}else{
startDateStr=startDateStr+"-"+number;
}
a++;
}else if(a==0){
startDateStr=""+number;
a++;
}else{
break;
}
}
}
if(a<3 || a>=4){
startDateStr="";
}
analyStartDate=startDateStr;
holidays.add(analyStartDate);
}
}catch(Exception e){
e.printStackTrace();
}
//获取第二列数据-工作日
String workDate="";
String workDateStr="";
try{
workDate=strArray[1].trim();
if(workDate=="" || workDate.equals("") || "\\".contains(workDate)){
workDate="";
}else{
Pattern pa = Pattern.compile("\\D+");
String[] numbers = pa.split(workDate);
int a=0;
for(String number:numbers){
if(null!=number && !"".equals(number)){
if(a>0 && a<3){
int i = Integer.parseInt(number);
if(i<10 && !number.contains("0")){
workDateStr=workDateStr+"-"+"0"+number;
}else{
workDateStr=workDateStr+"-"+number;
}
a++;
}else if(a==0){
workDateStr=""+number;
a++;
}else{
break;
}
}
}
if(a<3 || a>=4){
workDateStr="";
}
workDate=workDateStr;
workdays.add(workDate);
}
}catch(Exception e){
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
if (in != null) {
in.close();
}
}
}
}
如果输入的天数是负数则加判断:
HolidayWorkdayUtil h=new HolidayWorkdayUtil();
if(n<0){
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.set(Calendar.YEAR, c.get(Calendar.YEAR) - 1);//如果为负数,先把时间调回到一年前开始迭代
def nn=-n;
//println nn;
for(int i=0;i<=365;i++){
c.add(5, 1); //表示天加一
startDateStr=Util.dateParser1.format(c.getTime());
dayNum = h.getWorkDayNum(startDateStr,todayStr);
//println workday
if(dayNum==nn){
break;
}
}
workday=startDateStr;
}else{
workday = h.getWorkDay(todayStr,n);
}