自定义函数实现指定日期到今天的工作日

需求背景:
客户有这样的需求:给一个指定的日期和时限要求算出下一个时间来,要排除工作日、周末、国家法定节假日这3个条件,这个就要自定义函数来处理了,这样的需求在填报流程中使用的也是比较多的比如:第一个流程到第二个流程中间会2个小时的宽限时间,如果超出这2个小时审批就算超时把这个时间记录下来。


分析:
工作日:这个不同的季节上班时间可能会不一样
周末 : 这个可以公司随时自行定义
国家法定节假日:假如这个节假日中包含了周六、日要排除,不能重复的计算2次
可以看出上面几个参数都是可以灵活定义的


实现思路部分代码(具体见附件):

/**
* 获取下个月的指定日期
* @param day
* @return
*/
public String getNameDateTime(boolean isThisMonth,int day) {
StringBuffer overtime = new StringBuffer();
Calendar cal = getStartCal();
int year = cal.get(Calendar.YEAR);
int mon = cal.get(Calendar.MONTH)+1; //mon 日历从0开始计数

if (isThisMonth) {
int maxday = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
if (day > maxday)
day = maxday;
overtime.append(year).append(“-”);
if (mon < 10)
overtime.append(“0″);
overtime.append(mon).append(“-”);
if (day < 10)
overtime.append(“0″);
overtime.append(day).append(” 23:59″);
} else {
cal.roll(Calendar.MONTH,true);
int maxday = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
if (day > maxday)
day = maxday;
if (mon == 11) {
year = year + 1;
mon = 1;

overtime.append(year).append(“-”);
if (mon < 10)
overtime.append(“0″);
overtime.append(mon).append(“-”);
if (day < 10)
overtime.append(“0″);
overtime.append(day).append(” 23:59″);


return overtime.toString();
}


/**
* 根据工作时间计算超时时间点
* @param worklen 工作时间(小时)
* @return
*/
public Date calOvertime(float worklen) {

//将工作时间转换为秒
int timelen = (int)(worklen* 60);
String[] times = worktime.split(“,”);

//记录时间,如果当前是休息日,往后推
Calendar cal = getStartCal();
cal = getNextWorkDate(cal);
//扣除当前剩余时间
int lasttime = getLastWorktime();

//当天时间
if (timelen < lasttime) {
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
int cursec = hour * 60*60 + min*60;
for (int i=0;i<times.length;i++) {
String[] ss = times[i].split(“-”);
String s1 = ss[0];
String s2 = ss[1];
int pt1 = time2int(s1);
int pt2 = time2int(s2);
if (cursec > pt2) continue;

if (cursec < pt1 && timelen>pt2-pt1)
timelen = timelen – (pt2-pt1);
else if (cursec < pt2 && timelen>pt2-cursec)
timelen = timelen – (pt2-cursec);
else {
int yyyy = cal.get(Calendar.YEAR);
int mm = cal.get(Calendar.MONTH);
int dd = cal.get(Calendar.DATE);
if (cursec < pt1) cursec = pt1;
int hr = (cursec + timelen)/60/60;
int mi = (cursec + timelen)/60 % 60;
int sec = (cursec + timelen) % 60;
cal = new GregorianCalendar(yyyy, mm, dd, hr, mi, sec);
return cal.getTime();

}

}else {
timelen = timelen – lasttime;
cal = roll1Workday(cal);
}

int d1 = get1DWorktime();
while (timelen > d1) {
cal = roll1Workday(cal);
timelen = timelen – d1;
}

for (int i=0;i<times.length;i++) {
String[] ss = times[i].split(“-”);
String s1 = ss[0];
String s2 = ss[1];
int pt1 = time2int(s1);
int pt2 = time2int(s2);
if (timelen>pt2-pt1)
timelen = timelen – (pt2-pt1);
else {
int yyyy = cal.get(Calendar.YEAR);
int mm = cal.get(Calendar.MONTH);
int dd = cal.get(Calendar.DATE);
int hr = (pt1 + timelen)/60/60;
int mi = (pt1+timelen)/60 % 60;
int sec = (pt1+timelen) % 60;
cal = new GregorianCalendar(yyyy, mm, dd, hr, mi, sec);
break;


return cal.getTime();
}


/**
* 转换 节假日,如 5.1,5.2,5.1-7.1,没定义视为没有节假日,把-符号转成指定日期格式
* @param holiday
* @return
*/
private String makeHoliday(
String holiday) {
String strall = “,”;
if (holiday == null)
return “”;

holiday = holiday.trim();
String[] ss = holiday.split(“,”);
for (int i=0; i<ss.length; i++) {
String str = ss[i];
if (str.indexOf(“-”)==-1) {
strall = strall + str + “,”;
}else {
strall = strall + getAllday(str) + “,”;


return strall;
}

/**
* 将-转换为具体日期
* @param segdate
* @return
*/

private String getAllday(String segdate) {
int idx = segdate.indexOf(“-”);
String firstDatestr = segdate.substring(0,idx);
String lastDatestr = segdate.substring(idx+1);
Calendar firstDate = datestr2Calendar(firstDatestr);
Calendar lastDate = datestr2Calendar(lastDatestr);
String daystr = firstDatestr;
while (firstDate.before(lastDate)) {
firstDate.roll(Calendar.DAY_OF_YEAR,true);
int mon = firstDate.get(Calendar.MONTH);
int date = firstDate.get(Calendar.DAY_OF_MONTH);
daystr = daystr + “,” + (mon+1) + “.” + date;

return daystr;
}

/**
* 短格式日期字符串,如 5.1,4.3等
* @param datestr
* @return
*/
private Calendar datestr2Calendar(String datestr) {
Calendar cal = getStartCal();
int idx = datestr.indexOf(“.”);
int year = cal.get(Calendar.YEAR);
int month = Integer.parseInt(datestr.substring(0,idx));
int day = Integer.parseInt(datestr.substring(idx+1));

cal = new GregorianCalendar(year, month-1, day, 0, 0, 0);
return cal;

}

/**
* 将时间字符串转换为整数,以秒为单位,如8:30 –> 8*60*60+30*60
* @param timestr
* @return
*/
private int time2int(String timestr) {
int result = 0;
int idx = timestr.indexOf(“:”);
String hour = timestr.substring(0,idx);
String min = timestr.substring(idx+1);
result = Integer.parseInt(hour) * 60 * 60 + Integer.parseInt(min) * 60;
return result;
}

/**
* main方法
* @param args
*/
public static void main(String[] args) { //2009-10-23 8:54:19



/**

* @param subTime 提交时间 2011-6-16 22:22:12
* @param num 响应时限 分钟为单位
* @return
* @throws ParseException
*/
//接口调用方法———————–
public String getWorktime(String startTime,float num) throws ParseException{

SimpleDateFormat sdf=new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
Calendar startCal = Calendar.getInstance();
Date date = (Date) sdf.parse(startTime);
startCal.set(Calendar.YEAR, date.getYear()+1900);
startCal.set(Calendar.MONTH, date.getMonth());
startCal.set(Calendar.DAY_OF_MONTH, date.getDate());
startCal.set(Calendar.HOUR_OF_DAY, date.getHours());
startCal.set(Calendar.MINUTE, date.getMinutes());
startCal.set(Calendar.SECOND, date.getSeconds());

/**
* 假日参数可以在这里自定义
* @param startCal 提交时间 格式 2011-6-16 22:26:22
* @param holiday 节假日定义 格式 “5.1-5.5,8.18,11.24,4.28″
* @param workday 工作日定义 格式 1,2,3,4,5
* @param worktime 工作时间, 格式 8:30-12:00,14:30-18:30,没定义视为24小时制工作
*/
TESTWorktime wk = new TESTWorktime(startCal, “6.18″,null,”1,2,3,4,5″, null, “8:30-12:30,14:00-17:30″);

System.out.println(“开始日期”+sdf.format(startCal.getTime()));
System.out.println(“NUM———-”+num);
String str = String.valueOf(sdf.format(wk.calOvertime(num)));

return str;
}

public Calendar getStartCal() {
Calendar cal = Calendar.getInstance();
cal.setTime(startCal.getTime());
return cal;
}

public void setStartCal(Calendar startCal) {
this.startCal = startCal;
}


举例测试调用:


TESTWorktime w=new TESTWorktime();


System.out.println(w.getWorktime(“2011-06-17 13:50:35″, 243));


2011-06-17 13:50:35 它的243分钟以后就是 2011-06-20 09:03:00


注意 2011.6.18这天定义公司放假 18.19法定正好又为周末



前端报表用个自定义函数就可以实现到指定日期到今天的工作日(工作日可以在公共方法中定义)


热门文章