根据输入日期解决当月工作日和剩余工作日的自定义函数

第46章 根据输入日期解决当月工作日和剩余工作日的自定义函数

1. 问题概述
报表参数模板在第一次加载进来,需要根据当前的查询日期首先定位到属于当前月份的第几个工作日,当前月总共有多少个工作日,以及还剩下多个个工作日,如图:当前输入日期是2010-01-08, 当月总共20工作日,当前是第5工作日,剩余15工作日

此工作日的计算只是报表右上角的一部分,整个报表预览图如:

2. 算法及调用规则

A. 解决思路:
1.对于任意2个日期比如:date_start=2006-10-1、date_end=2006-10-14,首先计算这连个日期之间的时间间隔(天数),然后分别对date_start 和date_end 取得它们下一个星期一的日期.这样就可以得到一个新的可以整除7的完整日期间隔(这个新的日期间隔已经把星期几的问题剔出掉了).
2.换一种说法就是我们可以得到,这两个新的日期之间的周数,拿这个周数乘以5就是工作日期了(tmpWorkingDays),但是这个日期并不是我们所要的日期,接下来我们要做的就是计算date_start,date_end这两个日期对于根据它们所产生的新的日期之间的时间偏移量. date_start的偏移量(date_start_change)是需要加的,而date_end的这个偏移量(date_end_change)是需要减去的.
3.最后我们只要用tmpWorkingDays+date_start_change-date_end_change就是我们所要求的实际工作日了,以下是所有实现代码(两个日期跨年也没有问题)
B:报表参数模板上的用法:

C:自定义函数的登记:

3. 程序说明

调用格式:CalWorkDate(起始参数,结束参数);
例:=CalWorkDate(monthbegin(@arg1),monthend(@arg1))

package expression;

import java.util.Calendar;

import java.util.Date;

import com.runqian.base4.util.ReportError;

import com.runqian.report4.model.expression.Expression;

import com.runqian.report4.model.expression.Function;

import com.runqian.report4.model.expression.Variant2;

import com.runqian.report4.usermodel.Context;

public class CalWorkDate extends Function {

/**

* 主要思路: 对于任意2个日期比如:date_start=2006-10-1date_end=2006-10-14

* 首先计算这连个日期之间的时间间隔(天数),然后分别对date_start date_end 取得它们下一个星期一的日期,

* 这样就可以得到一个新的可以整除7的完整日期间隔(这个新的日期间隔已经把星期几的问题剔出掉了),

* 换一种说法就是我们可以得到,这两个新的日期之间的周数,拿这个周数乘以5就是工作日期了(tmpWorkingDays)。

* 但是这个日期并不是我们所要的日期,接下来我们要做的就是计算date_start,date_end这两个日期对于根据它们所产生的新的日期之间的时间偏移量,

* date_start的偏移量(date_start_change)是需要加的,而date_end的这个偏移量(date_end_change)是需要减去的。

* 最后我们只要用tmpWorkingDays+date_start_change-date_end_change就是我们所要求的实际工作日了。

* 以下是所有实现代码(两个日期跨年也没有问题)

*/

public Object calculate(Context ctx, boolean inputValue) {

if (this.paramList.size() == 0)

throw new ReportError(该函数需要两个日期参数!);

// 取得计算表达式

Expression exp1 = (Expression) this.paramList.get(0);

if (exp1 == null)

throw new ReportError(包含有无效参数!);

Object obj1 = Variant2.getValue(exp1.calculate(ctx, inputValue), false,

false);

Expression exp2 = (Expression) this.paramList.get(1);

if (exp2 == null)

throw new ReportError(包含有无效参数!);

Object obj2 = Variant2.getValue(exp2.calculate(ctx, inputValue), false,

false);

Date d1 = (Date) obj1;

Date d2 = (Date) obj2;

Calendar cal1 = Calendar.getInstance();

cal1.setTime(d1);

Calendar cal2 = Calendar.getInstance();

cal2.setTime(d2);

return new CalWorkDate().getWorkingDay(cal1,cal2);

}

public int getDaysBetween(java.util.Calendar d1, java.util.Calendar d2) {

if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end

java.util.Calendar swap = d1;

d1 = d2;

d2 = swap;

}

int days = d2.get(java.util.Calendar.DAY_OF_YEAR)

- d1.get(java.util.Calendar.DAY_OF_YEAR);

System.out.println(“d2:”+d2.get(java.util.Calendar.DAY_OF_YEAR));

System.out.println(“days:”+days);

int y2 = d2.get(java.util.Calendar.YEAR);

if (d1.get(java.util.Calendar.YEAR) != y2) {

d1 = (java.util.Calendar) d1.clone();

do {

days += d1.getActualMaximum(java.util.Calendar.DAY_OF_YEAR);

d1.add(java.util.Calendar.YEAR, 1);

} while (d1.get(java.util.Calendar.YEAR) != y2);

}

return days;

}

/**

* 计算2个日期之间的相隔天数

*

* @param d1

* @param d2

* @return

*/

public int getWorkingDay(java.util.Calendar d1, java.util.Calendar d2) {

int result = -1;

if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end

java.util.Calendar swap = d1;

d1 = d2;

d2 = swap;

}

int charge_start_date = 0;// 开始日期的日期偏移量

int charge_end_date = 0;// 结束日期的日期偏移量

// 日期不在同一个日期内

int stmp;

int etmp;

stmp = 7 – d1.get(Calendar.DAY_OF_WEEK);

etmp = 7 – d2.get(Calendar.DAY_OF_WEEK);

System.out.println(“stmp:”+stmp);

System.out.println(“etmp:”+etmp);

if (stmp != 0 && stmp != 6) {// 开始日期为星期六和星期日时偏移量为0

charge_start_date = stmp – 1;

}

if (etmp != 0 && etmp != 6) {// 结束日期为星期六和星期日时偏移量为0

charge_end_date = etmp – 1;

}

//

result = (getDaysBetween(this.getNextMonday(d1), this.getNextMonday(d2)) / 7)

* 5 + charge_start_date – charge_end_date;

System.out.println(“1:”+(getDaysBetween(this.getNextMonday(d1), this.getNextMonday(d2)) / 7)

* 5 );

System.out.println(“2:”+charge_start_date);

System.out.println(“3:”+charge_end_date);

return result;

}

/**

* 获得日期的下一个星期一的日期

*

* @param date

* @return

*/

public Calendar getNextMonday(Calendar date) {

Calendar result = null;

result = date;

do {

result = (Calendar) result.clone();

result.add(Calendar.DATE, 1);

} while (result.get(Calendar.DAY_OF_WEEK) != 2);

return result;

}

}

热门文章