SpringBoot 免費輕量級智能工作日判定方案:融合多源數據的節假日解決方案
前言
在金融交易、定時任務、報表生成、考勤系統等關鍵場景中,精準的工作日與節假日判定是系統核心基礎能力。
本文將深入探討 SpringBoot 如何構建高可靠、可擴展的工作日判定系統,解決法定節假日與調休帶來的復雜性問題。
一、免費開源類庫
holiday-cn 在 github 上有 1.6k star 的優秀類庫,實現自動每日抓取國務院公告獲取中國法定節假日數據,也支持提供在線數據獲取節假日數據。
- 提供 JSON 格式節假日數據
- CI 自動更新
- 數據變化時自動發布新版本 ( Watch - Release only 以獲取郵件提醒! )
- 提供 JSON 打包下載
1.1 數據格式
interface Holidays {
/** 完整年份, 整數。*/
year: number;
/** 所用國務院文件網址列表 */
papers: string[];
days: {
/** 節日名稱 */
name: string;
/** 日期, ISO 8601 格式 */
date: string;
/** 是否為休息日 */
isOffDay: boolean;
}[]
}1.2 在線使用
提示:任何第三方服務都可能故障或停止服務,如果穩定性要求高請自己搭建靜態文件服務。
- https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/{年份}.json
- https://cdn.jsdelivr.net/gh/NateScarlet/holiday-cn@master/{年份}.json
- https://fastly.jsdelivr.net/gh/NateScarlet/holiday-cn@master/{年份}.json
開源地址:https://github.com/NateScarlet/holiday-cn
二、免費第三方 API 集成
聚合數據與天行數據都提供了免費API接口獲取節假日數據。下面以聚合數據為例進行講解。
2.1 注冊
登錄官網進行注冊
2.2 API 申請
API 市場中找到“節假日信息查詢”,點擊進入,進行申請。
圖片
2.3 AppKey 獲取
申請完后,在數據中心,我的API 中找到對應 API,復制 AppKey,同時支持接口在線測試。
圖片
2.4 數據緩存本地
public class JuHeDateRefreshTask {
// 節假日信息查詢接
private static final String CALENDER_DAY_URL = "http://apis.juhe.cn/fapig/calendar/day?";
private static final String CALENDER_DAY_URL_APP_KEY = "AppKey";
private CalenderDayMapper calenderDayMapper;
public JuHeDateRefreshTask(CalenderDayMapper calenderDayMapper) {
this.calenderDayMapper = calenderDayMapper;
}
@Scheduled(cron = "0 30 1 * * ?")
public void refresh() {
Date now = new Date();
String nowDay = DateUtil.formatDate(now);
callCalenderDay(nowDay);
for(int i = 1; i<35; i++){
callCalenderDay(DateUtil.formatDate(DateUtil.offsetDay(now, i)));
}
}
private void callCalenderDay(String date){
CalenderDay calenderDay = calenderDayMapper.getOne("date", date);
if(calenderDay == null){
String param = "detail=1&key="+CALENDER_DAY_URL_APP_KEY+"&date="+date;
String response = HttpUtil.get(CALENDER_DAY_URL + param);
JSONObject jsonObject = JSONUtil.parseObj(response);
if(jsonObject.getInt("error_code") == 0){
JSONObject result = jsonObject.getJSONObject("result");
if(result != null){
calenderDay = buildCalenderDay(result);
calenderDayMapper.insert(calenderDay);
}
}else {
log.error("接口【"+CALENDER_DAY_URL + param+"】響應異常:"+jsonObject);
}
}
}
private CalenderDay buildCalenderDay(JSONObject result){
CalenderDay calenderDay = new CalenderDay();
calenderDay.setDate(result.getStr("date"));
calenderDay.setYear(result.getStr("year"));
calenderDay.setMonth(result.getStr("month"));
calenderDay.setDay(result.getStr("day"));
calenderDay.setCdStatus(result.getStr("status"));
calenderDay.setWeek(result.getStr("week"));
calenderDay.setCdStatusDesc(result.getStr("statusDesc"));
calenderDay.setAnimal(result.getStr("animal"));
calenderDay.setCnDay(result.getStr("cnDay"));
calenderDay.setCdValue(result.getStr("value"));
calenderDay.setCdDesc(result.getStr("desc"));
calenderDay.setGzDate(result.getStr("gzDate"));
calenderDay.setGzMonth(result.getStr("gzMonth"));
calenderDay.setGzYear(result.getStr("gzYear"));
calenderDay.setIsBigMonth(result.getStr("isBigMonth"));
calenderDay.setIMonth(result.getStr("lMonth"));
calenderDay.setIDate(result.getStr("lDate"));
calenderDay.setLunarYear(result.getStr("lunarYear"));
calenderDay.setLunarMonth(result.getStr("lunarMonth"));
calenderDay.setLunarDate(result.getStr("lunarDate"));
calenderDay.setSuit(result.getStr("suit"));
calenderDay.setAvoid(result.getStr("avoid"));
calenderDay.setTerm(result.getStr("term"));
calenderDay.setOriginal(result.toString());
return calenderDay;
}
}2.5. 相應結果
{
"reason": "success",
"result": {
"date": "2025-10-03",
"week": "星期五",
"statusDesc": "節假日",
"status": "1",
"animal": "蛇",
"avoid": "出行.栽種.納畜.安葬.行喪.伐木.造廟.造橋",
"cnDay": "五",
"day": "3",
"gzDate": "乙巳",
"gzMonth": "乙酉",
"gzYear": "乙巳",
"isBigMonth": "",
"jiri": "1",
"lDate": "十二",
"lMonth": "八",
"lunarDate": "12",
"lunarMonth": "8",
"lunarYear": "2025",
"month": "10",
"suit": "結婚.打掃.搬家.合婚訂婚.簽訂合同.交易.搬新房.開業.訂盟.祈福.安床.掛匾.祭祀.出火.收養子女.開光.求子",
"term": "",
"year": "2025"
},
"error_code": 0
}三、總結
系統穩定性建議:工作日判定系統應采用降級策略——當外部API不可用時自動切換至本地最新緩存數據,確保核心業務不受影響。


























