可以判断给定日期是否是工作日,以及两个日期间的工作日天数;该工具类依赖于Redis数据库,需要将整个年份的假期时间表存放到Redis中;假期时间表依赖于第三方接口。
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.beicai.compliance.util.redis.RedisUtil;
import org.elasticsearch.common.Strings;
import org.springframework.util.CollectionUtils;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
/**
* 假日实用程序
* 应用模块名称<p>
* 代码描述<p>
*
* @author ukou
* @date 2021/08/16
* @since 2021/8/7
*/
public class HolidayUtil {
// redis key格式前缀 -> calendar:workOrHolidays:year:month:day: + 1/2 1工作日 2假日
private static final String CALENDAR_WORKORHOLIDAYS = "calendar:workOrHolidays:";
private HolidayUtil() {
}
/**
* 是否是周末
*
* @return boolean
*/
public static boolean isWeekend() {
return isWeekend(LocalDate.now());
}
/**
* 是否是周末
*
* @param date 日期
* @return boolean
*/
public static boolean isWeekend(LocalDate date) {
DayOfWeek dayOfWeek = date.getDayOfWeek();
return DayOfWeek.SATURDAY.equals(dayOfWeek) || DayOfWeek.SUNDAY.equals(dayOfWeek);
}
/**
* 是否假日
*
* @return boolean
*/
public static boolean isHolidaysAndFestivals() {
return !isWorkday();
}
/**
* 是否假日
*
* @param date 日期
* @return boolean
*/
public static boolean isHolidaysAndFestivals(LocalDate date) {
return !isWorkday(date);
}
/**
* 是否工作日
*
* @return boolean
*/
public static boolean isWorkday() {
return isWorkday(LocalDate.now());
}
/**
* 是否工作日
*
* @param date 日期
* @return boolean
*/
public static boolean isWorkday(LocalDate date) {
if (date == null) {
return false;
}
String[] split = date.toString().split("-");
String s = RedisUtil.get(CALENDAR_WORKORHOLIDAYS + split[0] + ":" + split[1] + ":" + split[2]);
if (s == null) {
saveCalendarToRedis(date);
s = RedisUtil.get(CALENDAR_WORKORHOLIDAYS + date.getYear() + ":" + date.getMonth() + ":" + date.getDayOfMonth());
}
return Objects.equals(s, "1");
}
// 拉取第三方假期时间表
private static void saveCalendarToRedis(LocalDate date) {
String url = "https://api.apihubs.cn/holiday/get?field=date,workday&year=" + date.getYear() + "&size=366";
String body = HttpRequest.get(url).execute().body();
HashMap<String, String> bodyResult =
JSON.parseObject(body, new TypeReference<HashMap<String, String>>() {});
HashMap<String, String> dataResult =
JSON.parseObject(bodyResult.get("data"), new TypeReference<HashMap<String, String>>() {});
List<Map<String, String>> result =
JSON.parseObject(dataResult.get("list"), new TypeReference<List<Map<String, String>>>() {});
if (!CollectionUtils.isEmpty(result)) {
for (Map<String, String> map : result) {
String key = CALENDAR_WORKORHOLIDAYS + Strings.substring(map.get("date"), 0, 4) + ":" +
Strings.substring(map.get("date"), 4, 6) + ":" + Strings.substring(map.get("date"), 6, 8);
RedisUtil.put(key, map.get("workday"));
}
}
}
/**
* 获取两个日期的工作日差
*
* @param before 在此之前
* @param after 之后
* @return {@link Integer}
*/
public static Integer getDifference(LocalDate before, LocalDate after) {
if (before == null || after == null) {
return null;
}
Integer difference = 0;
while (!before.isAfter(after)) {
if (isWorkday(before)) {
++ difference;
}
before = before.plusDays(1);
}
return difference;
}
}