`
bobo
  • 浏览: 86356 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

支持节假日及调休的工作日历实现

阅读更多
支持节假日及调休的工作日历实现

最近产品及项目中要用到工作日历, 找了一下发现jBPM的工作日历BusinessCalendar可用, 但缺少对节假日调休的支持, 通过简单改造实现了节假日调休和中文配置

主要修改如下:
1\ 在假日维护中增加一个加班或调休的定义维护
public class Holiday{
public static List parseOvertimes(Properties calendarProperties,
			BusinessCalendar businessCalendar) {
		List overtimes = new ArrayList();

		DateFormat dateFormat = new SimpleDateFormat(
				calendarProperties.getProperty("day.format"));
		Iterator iter = calendarProperties.keySet().iterator();
		while (iter.hasNext()) {
			String key = (String) iter.next();
			if (key.startsWith("overtime")) {
				Holiday holiday = new Holiday(
						calendarProperties.getProperty(key), dateFormat,
						businessCalendar);
				overtimes.add(holiday);
			}
		}
		return overtimes;
	}
}

2\ 查找工作日时如发现为非工作日则检查是否为加班或调休
public class BusinessCalendar{

       public Day findDay(Date date) {
		Calendar calendar = getCalendar();
		calendar.setTime(date);
		Day day = weekDays[calendar.get(Calendar.DAY_OF_WEEK)];
		
		//当某天无工作时间时检查是否有加班或调休
		if(day==null || day.dayParts==null || day.dayParts.length==0){
			if(isOvertime(date)){
				day = weekDayCommon;
			}
		}
		
		return day;
	}

}

3\ 扩展BusinessCalendar的add方法支持Calendar的add方法
public class BusinessCalendar{

       /**
	 * 工作日历计算
	 * @param date 初始时间
	 * @param field 时间单位,同Calendar
	 * @param amount  时间数量
	 * @return 按工作日历计算后时间
	 */
	public Date add(Date date, int field, int amount){
		return add(date, field, amount, true);
	}
	
	public Date add(Date date, int field, int amount, boolean isBusinessTime){
		Date end = null;
		if (isBusinessTime) {
			DayPart dayPart = findDayPart(date);
			boolean isInbusinessHours = (dayPart != null);
			if (!isInbusinessHours) {
				Object[] result = new Object[2];
				findDay(date).findNextDayPartStart(0, date, result);
				date = (Date) result[0];
				dayPart = (DayPart) result[1];
			}
			end = dayPart.add(date, field, amount);
		} else {
			Calendar calendar = getCalendar();
			calendar.setTime(date);
			calendar.add(field, amount);
			end = calendar.getTime();
		}
		return end;
	}
}

3\ 增加Duration支持中文定义
public class DayPart{

        public Duration(String duration) {
		if (duration == null)
			throw new NullPointerException("duration is null");
		
		
		int separatorIndex = -1;
		String quantityText = null;
		String unitText = null;
		
		//检查空格 for english formate
		separatorIndex = duration.indexOf(' ');
		if (separatorIndex>1){
			quantityText = duration.substring(0, separatorIndex).trim().toLowerCase();
			unitText = duration.substring(separatorIndex + 1).trim().toLowerCase();	
			if (unitText.startsWith("business")) {
				isBusinessTime = true;
			}
		}
		//检查中文"工作"
		if(separatorIndex<=0){
			separatorIndex = duration.indexOf("工作");
			if(separatorIndex>0){
				isBusinessTime = true;
				quantityText = duration.substring(0, separatorIndex).trim().toLowerCase();
				unitText = duration.substring(separatorIndex + 2).trim().toLowerCase();		
			}			
		}
		//逐字符检查
		if(separatorIndex<=0){
			for(int i=0; i<duration.length(); i++){
				char ch = duration.charAt(i);
				if((48<=ch && ch<=57) || ch==46){
					continue;
				}
				//第一个非数字和.
				quantityText = duration.substring(0, i).trim().toLowerCase();	
				unitText = duration.substring(i).trim().toLowerCase();	
			}
			if(quantityText==null){
				quantityText = duration;
			}
			if(unitText==null || "".equals(unitText)){
				unitText = "H";
			}
		}
				
		double amount = Double.parseDouble(quantityText);
		Long unit = (Long) units.get(unitText);
		this.milliseconds = (long) (amount * unit.longValue());
	}

       static {
		units = new HashMap();
		units.put("second", new Long(SECOND));
		units.put("seconds", new Long(SECOND));
		units.put("秒", new Long(SECOND));
		units.put("S", new Long(SECOND));
		units.put("s", new Long(SECOND));
		units.put("business second", new Long(SECOND));
		units.put("business seconds", new Long(SECOND));
		units.put("minute", new Long(MINUTE));
		units.put("minutes", new Long(MINUTE));
		units.put("分钟", new Long(MINUTE));
		units.put("Min", new Long(MINUTE));
		units.put("min", new Long(MINUTE));
		units.put("business minute", new Long(MINUTE));
		units.put("business minutes", new Long(MINUTE));
		units.put("hour", new Long(HOUR));
		units.put("hours", new Long(HOUR));
		units.put("小时", new Long(HOUR));
		units.put("时", new Long(HOUR));
		units.put("H", new Long(HOUR));
		units.put("h", new Long(HOUR));
		units.put("business hour", new Long(HOUR));
		units.put("business hours", new Long(HOUR));
		units.put("day", new Long(DAY));
		units.put("days", new Long(DAY));
		units.put("天", new Long(DAY));
		units.put("日", new Long(DAY));
		units.put("D", new Long(DAY));
		units.put("d", new Long(DAY));
		units.put("business day", new Long(BUSINESS_DAY));
		units.put("business days", new Long(BUSINESS_DAY));
		units.put("week", new Long(WEEK));
		units.put("weeks", new Long(WEEK));
		units.put("星期", new Long(WEEK));
		units.put("周", new Long(WEEK));
		units.put("W", new Long(WEEK));
		units.put("w", new Long(WEEK));
		units.put("business week", new Long(BUSINESS_WEEK));
		units.put("business weeks", new Long(BUSINESS_WEEK));
		units.put("month", new Long(MONTH));
		units.put("months", new Long(MONTH));
		units.put("月", new Long(MONTH));
		units.put("M", new Long(MONTH));
		units.put("m", new Long(MONTH));
		units.put("business month", new Long(BUSINESS_MONTH));
		units.put("business months", new Long(BUSINESS_MONTH));
		units.put("year", new Long(YEAR));
		units.put("years", new Long(YEAR));
		units.put("年", new Long(YEAR));
		units.put("Y", new Long(YEAR));
		units.put("y", new Long(YEAR));
		units.put("business year", new Long(BUSINESS_YEAR));
		units.put("business years", new Long(BUSINESS_YEAR));
	}
}



BusinessCalendar配置文件范例
## 工作日及工作时间定义
hour.format=HH:mm   
#weekday ::= [<daypart> [& <daypart>]*]   
#daypart ::= <start-hour>-<to-hour>  
#start-hour and to-hour must be in the hour.format   
#dayparts have to be ordered   
weekday.common=9:00-12:00 & 12:30-17:00  #通用工作时间, 周末调休会用到
weekday.monday=9:00-12:00 & 12:30-17:00 
weekday.thuesday=9:00-12:00 & 12:30-17:00
weekday.wednesday=9:00-12:00 & 12:30-17:00
weekday.thursday=9:00-12:00 & 12:30-17:00
weekday.friday=9:00-12:00 & 12:30-17:00
weekday.saturday=
weekday.sunday=

## 节假日及加班调休定义
day.format=yyyy/MM/dd
# holiday syntax: <holiday>  
# holiday period syntax: <start-day>-<end-day>  
# below are the belgian official holidays 
#元旦  
holiday.1=2012/01/01-2012/01/03
#春节 
holiday.2=2012/01/22-2012/01/28
overtime.2=2012/01/21
overtime.2a=2012/01/29
#清明
holiday.3=2012/04/02-2012/04/04
overtime.3=2012/03/31-2012/04/01
#五一
holiday.4=2012/04/29-2012/05/01
overtime.4=2012/04/28
#端午   
holiday.5=2012/06/22-2012/06/24 
#中秋 
holiday.6=2012/09/30
#国庆
holiday.7=2012/10/01-2012/10/07
overtime.7=2012/09/29

## 其他参数定义  
business.day.expressed.in.hours=8
business.week.expressed.in.hours=40
business.month.expressed.in.business.days=21
business.year.expressed.in.business.days=220


jBPM BusinessCalendar.java
http://kickjava.com/src/org/jbpm/calendar/BusinessCalendar.java.htm
OBE1.0 BusinessCalendar.java
https://java2s.com/Open-Source/Java/Workflow-Engines/obe-1.0/org/obe/engine/calendar/BusinessCalendar.java.htm
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics