突然来了个需求,要在考勤系统上根据每年的节假日自动设置休息日。
于是在网上各种找计算节假日是怎么调休的,找了各种资源,第三方网站,都感觉不怎么满意。
知道看到了一篇将百度的日历页面的数据拉下来的方法:
于是,跟着上面提供的方法,开始搞接口:
package com.weroom.core.util.holidayUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.weroom.core.domain.result.HolidayResult;
import com.weroom.core.utils.JsonUtils;
import com.weroom.core.utils.StringUtils;
import lombok.extern.log4j.Log4j2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Log4j2
public class BaiduHolidayUtil {
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "/" + param;
URL realUrl = new URL(urlNameString);
URLConnection connection = realUrl.openConnection();
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.connect();
String contentType = connection.getContentType();
String charset = "";
if (contentType != null) {
charset = contentType.replaceAll(".*charset=([^\"]+).*", "$1");
}
in = new BufferedReader(new InputStreamReader(connection.getInputStream(),charset));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
public static void main(String[] args) {
//开始的年份
int startYear = 2024;
List<HolidayResult> allList = loop(startYear+"");
System.out.println(JsonUtils.object2JsonNoEscaping(allList));
System.out.println(allList.size());
}
public static List<HolidayResult> loop(String year) {
List<HolidayResult> resultList = new ArrayList<>();
for(int j = 1; j <= 12; j++) {
String s = BaiduHolidayUtil.sendGet("https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query="+year+"%E5%B9%B4"+j+"%E6%9C%88&co=&resource_id=39043&t=1617089428269&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=wisetpl&cb=jQuery110203576901702188473_1617089118772&_=1617089118776", "");
if (StringUtils.isBlank(s)) {
continue;
}
s = s.substring(s.indexOf("("));
s = s.substring(1, s.length() - 2);
Map<String, Object> map = (Map<String, Object>) JSONObject.parse(s);
List list = (List) map.get("data");
if (CollectionUtil.isEmpty(list)) {
continue;
}
Map data = (Map) list.get(0);
if (null == data) {
continue;
}
List<Map> almanac = (List<Map>) data.get("almanac");
if(almanac == null || almanac.size() == 0) {
continue;
}
//只以下几个节日输出名称,其他的(如世界读书日等) 不输出
List<String> holidayNameList = new ArrayList<>();
holidayNameList.add("春节");
holidayNameList.add("元旦");
holidayNameList.add("除夕");
holidayNameList.add("清明");
holidayNameList.add("劳动节");
holidayNameList.add("端午节");
holidayNameList.add("中秋节");
holidayNameList.add("国庆节");
for(int i = 1; i < almanac.size(); i++) {
String key = ((String)almanac.get(i).get("oDate")).substring(0, 10);
String status = (String)almanac.get(i - 1).get("status");
Object obj = almanac.get(i-1).get("festivalList");
if("1".equals(status) || "2".equals(status)) {
HolidayResult result = new HolidayResult();
result.setDay(key);
result.setState(status);
if (null != obj && holidayNameList.contains(obj.toString())) {
result.setName(obj.toString());
}
resultList.add(result);
}
}
}
//去重并排序
if (CollectionUtil.isNotEmpty(resultList)) {
Map<String,HolidayResult> map = resultList.stream()
.filter(Objects::nonNull)
.filter(a -> a.getDay() != null && a.getDay().contains(year))
.collect(Collectors.toMap(a -> a.getDay(), Function.identity(),(v1,v2) -> v1));
resultList = new ArrayList<>(map.values());
resultList.sort(Comparator.comparing(HolidayResult :: getDay));
}
return resultList;
}
}
输出的结果:
其中state=1表示休息,state=2表示上班