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

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

最近产品及项目中要用到工作日历, 找了一下发现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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值