支持节假日及调休的工作日历实现
最近产品及项目中要用到工作日历, 找了一下发现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
分享到:
相关推荐
本文将详细探讨如何实现一个年日历,包括维护工作日和休息日,以及初始化法定节假日,主要涉及的技术栈是Vue.js,一个流行的前端JavaScript框架。 首先,我们需要理解年日历的基本构成。年日历通常会展示一年中的12...
压缩包里有2个文件,用于计算两个日期相差的工作日天数(排除周末和法定节假日)...2、SQL文件为2023年所有日期的插入SQL,并标注:工作日、法定节假日、节假日调休的上班日 、周末的类型。 3、已重新更正5月6日调休。
推荐理由:中国节假日日历是一个包含节假日、调休和补班信息的ICS格式日历。可供iPhone、Google Calendar、Outlook等客户端订阅,同时包含了节假日API。用户可以方便地获取并同步中国的各项假期信息,轻松规划生活和...
2024年日历 中文版 横向排版 周一开始 带农历 带节假日调休 - 模板[DF011]
"js带节假日日历控件"就是一种利用JavaScript实现的,包含节假日信息的日历组件。 创建这样的日历控件首先需要了解JavaScript的基本语法,包括变量声明、数据类型、条件语句、循环结构、函数等。同时,由于我们需要...
调休:法定上班 节假日:法定休息 周六周日:周末 其他日期:工作日 数据来源:万年历
周六周日:周末 其他日期:工作日
调休:法定上班 节假日:法定休息 周六周日:周末 其他日期:工作日
2023年所有日期数据(区分周末、节假日、工作日) mysql 语句 insert 生成的节假日表 code字段状态: 工作日:0 法定节假日:1 休息日加班(法定节假日调休):2 休息日(日常休息日):3 mysql2023日期数据全部.sql
2023年日历 中文版 横向排版 周一开始 带农历 带节假日调休 - 模板[DF011]
苹果的日历是没有显示中国的法定节假日的,这个想必小伙伴们都知道,但可以通过添加日历订阅来实现,这个方法至今也是好用的,不过需要那啥才行,对于大部分小伙伴并不能手动进行添加并订阅日历,通过这篇文章就为...
2023年所有日期数据(区分周末、节假日、工作日) mysql 语句 insert 生成的节假日表 code字段状态: 工作日:0 法定节假日:1 休息日加班(法定节假日调休):2 休息日(日常休息日):3 mysql2023日期数据全部.sql
周六周日:周末 其他日期:工作日
2024年全年日历excel,A4横排,包含2024最新发布放假安排,调休日提醒,可编辑,手工制作,含节气,农历,放假安排 2024年将有七个法定放假日, 元旦:12月30日至1月1日放假3天,不调休 春节:2月10日至17日放假...
总之,这个JavaScript示例代码提供了一个基本的法定节假日判断方法,对于开发具有日历功能的应用,特别是涉及到工作日计算的场景,具有一定的实用价值。开发者可以根据自己的需求进行适当的修改和扩展。
在Java编程中,生成节假日对照表是一个常见的需求,特别是在开发涉及日期处理和日程安排的...在实际应用中,这样的工具类还可以扩展,比如增加对其他国家和地区节假日的支持,或者集成到日历应用中,提供更丰富的功能。
调休:法定上班 节假日:法定休息 周六周日:周末 其他日期:工作日
针对标题"Java实现将每年的节假日,周末,工作日详情记录至数据库表中",我们可以详细讨论以下几个关键知识点: 1. **日期处理库**: Java中,`java.time`包提供了强大的日期时间处理功能,例如`LocalDate`类用于...
天行数据API提供了一系列接口,用于获取各种实用信息,其中包括查询节假日、调休、工作日和周末日期的功能。这个功能对于开发需要处理时间计算或者日程管理的Java应用来说尤其有用。本文将详细介绍如何在Java中使用...
2. 数据结构设计:在小程序中,我们需要创建一个数据结构来存储当前月份的所有日期,包括公历和农历日期、是否为工作日、是否为节假日、是否需要补班等信息。 二、农历转换 1. 农历算法:为了在日历中显示农历,...