一、判断日期是否是工作日主要有两种方式。
1.默认周一到周五为工作日。
优点:简单省事。
缺点:是如果遇上调休/补班有可能工作日变休息日,休息日变工作日,如2023.09.29本来是周五工作日,但是因为是中秋节变成了假期。
2.将今年的节日假期和补班存进数据库中。
优点:判断是否是工作日准确,不会出现方法1缺点的问题。
缺点:需要维护该数据库的数据,每年的假期/补班日期不一样。
我选择的是第二种方式,虽然麻烦但是准确。第一种方式在代码中也有体现在下面的代码中我会标注出来(二.4判断指定日期是否是工作日代码块中的try代码就是)。
二、代码实现
1.获取假期/调休的数据源
(1) https://timor.tech/api/holiday/year
上面这个链接可以查询当前年中所有的假期和调休日期,如果想了解该链接详细内容可以输入下面这个链接查看具体说明。
(连接1)该接口返回的数据格式如下图所示:
2.创建数据库
CREATE TABLE `demo` (
`ID` char(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'ID',
`AFTER` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '只在调休下有该字段。true表示放完假后调休,false表示先调休再放假',
`DATE` timestamp NULL DEFAULT NULL COMMENT '节假日的日期',
`HOLIDAY` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'true表示是节假日,false表示是调休',
`NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '节假日的中文名。如果是调休,则是调休的中文名,例如\'国庆前调休\'',
`REST` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '表示当前时间距离目标还有多少天。比如今天是 2018-09-28,距离 2018-10-01 还有3天',
`TARGET` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '只在调休下有该字段。表示调休的节假日',
`WAGE` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '薪资倍数,1表示是1倍工资',
`IS_DELETE` char(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
数据库我是根据链接1返回的数据设计的表字段,每个字段是做什么的已经在备注中表明。
3.创建维护假期表数据的接口
创建 controller、entity、mapper等等我就省略了,该实体的名称我以"demo"代称。
demoServiceImpl(接口的sql直接按照注释的写就行了在这里我就不赘述了)
/**
* 方法描述: 插入新的假期数据
* @param params
* @return: Boolean
*/
@Override
public Boolean saveDemo(JSONObject params) {
Boolean pan = false;
//执行之前先将数据库中的数据删除 防止出现脏数据 直接将之前所有数据全假删除就行了反正以后也用不到了
demoMapper.delete();
//批量新增数据
pan = saveOrUpdateBatch(params);
return pan;
}
4.判断指定日期是否是工作日
接口描述:判断dateTime是不是工作日 是返回true 不是返回false。
业务逻辑:如果dateTime不是空那么就查询该时间,如果为空则new Date()当前时间,先去查询demo表看看有没有今天的数据,如果有数据判断是不是工作日,如果没有数据则判断该时间是不是在周一到周五之间如果是返回true不是返回false。
/**
* 方法描述: 判断该日期是否是工作日
* @param dateTime
* @return: Boolean
*/
@Override
public Boolean verdictIsWorkDay(String dateTime) {
Boolean isWorkDay = false;
//创建时间格式
DateFormat fmt =new SimpleDateFormat("yyyy-MM-dd");
String strDate = "";
//如果dataTime不是空 则将该值转为date
if(StringUtil.isNotEmpty(dateTime)){
strDate = dateTime;
}else{
strDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
}
//时间不能为空
if(StringUtil.isNotEmpty(strDate)){
//去假期补休数据库中查看是否有该天数据
Map query = new HashMap<>(16);
query.put("date", strDate);
//queryDemo 根据时间匹配demo表中的date字段并且isDelete是未删除的的数据
JSONArray demos = demoMapper.queryDemo(query);
//如果有今天的数据则判断holiday的值是否是false(true 是假期 false不是假期)
if(demos.size() > 0){
JSONObject demo = demos.getJSONObject(0);
//如果holiday字段是false证明今天是工作日
if("false".equals(demo.get("holiday").toString()){
isWorkDay = true;
}
}else{
//没有数据则判断是星期几 周一到周五为工作日
//如果只想根据周一到周五判断是不是工作日 只需要try里面的代码就行了
try {
String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Calendar cal = Calendar.getInstance();
cal.setTime(fmt.parse(strDate));
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0){
w = 0;
}
String weekDay = "1,2,3,4,5";
if(weekDay.indexOf(ConvertUtil.toString(w)) != -1){
isWorkDay = true;
}else{
isWorkDay = false;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
return isWorkDay;
}
5.数据库的查询语句
DATEDIFF(date, now()) = 0可以判断是不是当天的数据,如果需要查询指定日期只需要替换now()就可以了,DATEDIFF好处是不用限制yyyy-MM-dd还是yyyy-MM-dd HH:mm:ss
select
ID, `AFTER`, `DATE`, HOLIDAY, NAME, REST, TARGET, WAGE, IS_DELETE
from
demo
where
DATEDIFF(date, now()) = 0 and is_delete = '0'