1、背景:
很多场景,需要实现统计工作时长,例如:9:00-18:00 以每天工作9小时为1天,同时需要基于法定节假日(即:国务院会在每年最后一个月公布下一年度法定节假日,涉及工作日为休息,休日为补班情况,导致工作时间天数无法按照周六日模式计算),故:为满足此场景,本组件实现基于 万年历 (需根据国务院公布的法定节假日:每年初维护1次 ),通过公用工具类实现动态获取数据,以确保离线(无法访问外网)情况下,工作日历天数的准确性。(很多组件基于互联网接口,本组件可离线使用)
2、设计思路:
2.1、通过以上背景,此工作日历 需要维护 国务院公布的法定节假日 及 补班日,同时基于万年历(含阴历), 参考百度【2022日历】效果,方便运维人员维护 法定节假日,同时可以直观的展示节假日数据是否准确。
2.2、组件可满足分布式部署(即:多台服务器部署应用,高可用),未使用 缓存 或 Redis,使用DB表存储 法定节假日及补班数据。(G_SYS_CALENDAR - 系统工作日历表:存储 法定节假日 及 补班数据,其他正常工作日和周六日不存储)
2.3、为方便维护管理,此功能只对系统管理员开发,不对业务开放。故:工作日历效果在后端实现。使用Freemarker技术,未采用vue前后端 分离实现。(即:后端页面一体化实现)
3、实现效果:
4、万年历(工作日历)管理功能说明:
1)全年日历信息展示(包含阴历)。
2)年、月、今日 快速切换展示。
3)法定节假日/补班日 标识展示,可与百度日历核对数据是否维护准确。
4)选择对应日期,自动根据后端获取 日期类型(工作/补班日 还是 非工作日/节假日)。
5)选择日期和类型后,点击【保存】按钮,自动异步存储数据,同时局部刷新实时渲染日历标记(休/班)。
5、工作日代码工具类:com.demo.common.calendar.util.CalendarHelper
package com.demo.common.calendar.util;
/**
* Created on 2022/12/02
* 万年历工具类辅助类,用于获取 万年历中的 工作日+补班(调休日) 等信息,方便用于数据计算
* 本类需要根据 国务院每年年底 公布的第二年节假日安排,进行一次维护 节假日、补班 日等信息后,自动根据db中存储的数据进行计算工作日天数.
*
* @author: herb
*/
public class CalendarHelper{
略
}
6、对外提供方法:
方法代码 | 方法参数 | 方法说明 | 其它说明 |
CalendarHelper. isDateYYYY_MM_DD(String date) | * @param date 日期字符串 yyyy-MM-dd * @return boolean true=日期格式;false=非法日期格式 | * 匹配校验格式 * 匹配日期:1900-01-01、2205-02-31、2999-12-31 * 不匹配日期:1899-12-31、2018-05-35、2018-13-05、3000-01-01、2018-01-XX | 静态方法,可直接调用 |
CalendarHelper. isWorkingDay(long time) | * @param time 当前日期时间戳毫秒数 * @return boolean true=工作日,false=非工作日(节假日) | * 校验当前日期是否为工作日 (已包含维护的调休工作日) | 静态方法,可直接调用 |
CalendarHelper. getWorkingDays(Date start, Date end) | * @param start 开始日期 * @param end 结束日期 * @return int 工作日天数(包含 节假日补班天数) | * 获取计算工作日(包含法定节假日和调休) * 【以2022官方法定节假日来讲】: * 1月=21天 * 2月=16天 * 3月=23天 * 依次类推 | 静态方法,可直接调用 |
CalendarHelper. getHoliDays(Date start, Date end) | * @param start 开始日期 * @param end 结束日期 * @return int 非工作日+节假日 总天数(包含节假日) | * 获取计算休息日(包含法定节假日) * 【以2022 官方法定节假日来讲】: * 1月=10天 (元旦3天+周六日6天+ 31日 1天) * 2月=12天 (春节6天 (1月31日不进来) + 周六日6天) * 3月=8天(周六日 8天) 依次类推 | 静态方法,可直接调用 |
ada
/**
* 获取工作日天数/休息日天数
* @param args
*/
public static void main(String[] args) {
//开始日期
String startDateStr = "2022-02-01";
Date startDt = DateUtil.parse(startDateStr);
//结束日期
String endDateStr = "2022-03-31";
Date endDt = DateUtil.parse(endDateStr);
//输出工作日天数
int workDt = CalendarHelper.getWorkingDays(startDt, endDt);
System.out.println(startDateStr + "至 " + endDateStr + " 》工作日天数为:" + workDt + "天");
//输出 非工作日+节假日 天数
int holidays = CalendarHelper.getHoliDays(startDt, endDt);
System.out.println(startDateStr + "至 " + endDateStr + " 》可休息天数为:" + holidays + "天");
}