java获取国家法定节假日(不依赖API)
短信预约 -IT技能 免费直播动态提醒
java获取国家法定节假日, 由此可获取每月第一个工作日和最后一个工作日
(不依赖API,主要是因为API接口不可靠或计费,此工具依赖国务院发布的节假日基础信息进行解析)
本工具仅供参考学习。各类数据获取需遵守法律法规
package com.exrate;import cn.hutool.core.util.NumberUtil;import okhttp3.*;import org.apache.commons.lang3.StringUtils;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import java.io.*;import java.time.LocalDate;import java.time.format.DateTimeFormatter;import java.util.*;import java.util.concurrent.ConcurrentSkipListSet;import java.util.regex.Matcher;import java.util.regex.Pattern;public class ChinaHolidaysUtils { private static final String HOLIDAY_NOTICES_FILE_PATH = ChinaHolidaysUtils.class.getResource("/").getPath()+"国务院发布的节假日安排的通知/"; private static final String GOV_URL = "http://sousuo.gov.cn/s.htm?t=paper&advance=false&n=10&timetype=timeqb&mintime=&maxtime=&sort=pubtime&q=%E8%8A%82%E5%81%87%E6%97%A5%E5%AE%89%E6%8E%92%E7%9A%84%E9%80%9A%E7%9F%A5"; private static Set publicHolidays = new ConcurrentSkipListSet<>(); private static Set oxenHorseDays = new ConcurrentSkipListSet<>(); public static void main(String[] args) { try { System.out.println(isOxenHorseDays(LocalDate.now().toString())); } catch (IOException e) { e.printStackTrace(); } System.out.println("publicHolidays: " + publicHolidays); System.out.println("oxenHorseDays: " + oxenHorseDays); } public static boolean isOxenHorseDays(String localDate) throws IOException { if(oxenHorseDays.isEmpty()){ getDays(localDate, publicHolidays, oxenHorseDays); } return oxenHorseDays.contains(localDate); } public static boolean isPublicHolidays(String localDate) throws IOException { if(publicHolidays.isEmpty()){ getDays(localDate, publicHolidays, oxenHorseDays); } return publicHolidays.contains(localDate); } private static synchronized void getDays(String localDate, Set publicHolidays, Set oxenHorseDays) throws IOException { //获取xxx年的节假日数据 String year = null; if(StringUtils.isEmpty(localDate)){ year = String.valueOf(LocalDate.parse(localDate).getYear()); }else{ year = String.valueOf(LocalDate.now().getYear()); } //先通过缓存文件,否则使用http获取 String html = getHtmlByCacheFiles(year); if(html == null){ html = getHtmlByHttp(year); } Document doc = Jsoup.parse(html); Element content = doc.select("div.b12c.pages_content").first(); Elements paragraphs = content.select("p"); for (Element p : paragraphs) { String text = p.text(); if (text.contains("、") && text.contains(":") && text.contains("。") && text.contains("放假")) { text = text.substring(text.indexOf(":")+1); String[] sentences = text.split("。"); for (String sentence : sentences) { if (sentence.contains("放假")) { String t = sentence.split("放假")[0]; if (t.contains("至")) {String start = t.split("至")[0];String startDay=null, startMonth=null, startYear=null;if(start.contains("日") || start.contains("月") || start.contains("年")){ startDay = getDigit(start, "日"); startMonth = getDigit(start, "月"); startYear = getDigit(start, "年");}LocalDate startDate = parseDate(startYear==null?year:startYear, startMonth, startDay);String end = t.split("至")[1];String endDay=null, endMonth=null, endYear=null;if(end.contains("日") || end.contains("月") || end.contains("年")){ endDay = getDigit(end, "日"); endMonth = getDigit(end, "月"); endYear = getDigit(end, "年");}LocalDate endDate = parseDate(endYear==null?(startYear==null?year:startYear):endYear, endMonth==null?startMonth:endMonth, endDay);for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) { publicHolidays.add(date.toString());} } else {String tDay=null, tMonth=null, tYear=null;if(t.contains("日") || t.contains("月") || t.contains("年")){ tDay = getDigit(t, "日"); tMonth = getDigit(t, "月"); tYear = getDigit(t, "年");}LocalDate date = parseDate(tYear==null? year:tYear, tMonth, tDay);publicHolidays.add(date.toString()); } } if (sentence.contains("上班")) { if (sentence.contains("、")) {String[] dates = sentence.split("、");for (String dateStr : dates) { String tDay=null, tMonth=null, tYear=null; if(dateStr.contains("日") || dateStr.contains("月") || dateStr.contains("年")){ tDay = getDigit(dateStr, "日"); tMonth = getDigit(dateStr, "月"); tYear = getDigit(dateStr, "年"); } LocalDate date = parseDate(tYear==null? year:tYear, tMonth, tDay); oxenHorseDays.add(date.toString());} } } } } } } private static Request getRequestSetUnifiedHead(String url){ Request.Builder builder = new Request.Builder(); builder.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36") .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,* private static String httpGet(OkHttpClient client, String url) throws IOException { Request request = getRequestSetUnifiedHead(url); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) { throw new IOException("获取数据失败:" + url); } String html = response.body().string(); System.out.println("进行了一次http get请求:" + url); return html; } private static String getHtmlByHttp(String year) throws IOException { OkHttpClient client = new OkHttpClient(); String html = httpGet(client, GOV_URL); Document doc = Jsoup.parse(html); Elements resList = doc.select("li.res-list"); if (!resList.isEmpty()) { Optional optional = resList.stream().filter(res -> res.text().contains("国务院办公厅关于"+year+"年")).findFirst(); if (!optional.isPresent()) { throw new IOException("未获取到"+ year +"年节假日安排的通知:" + GOV_URL); } Element element = optional.get(); String linkUrl = element.select("a[href]").attr("abs:href"); html = httpGet(client, linkUrl); str2File(html, HOLIDAY_NOTICES_FILE_PATH, year+"节假日安排的通知-源数据", ".html"); Document resDoc = Jsoup.parse(html); str2File(html, HOLIDAY_NOTICES_FILE_PATH, resDoc.title(), ".html"); return html; } return null; } private static String getHtmlByCacheFiles(String year) { String[] paths = new File(HOLIDAY_NOTICES_FILE_PATH).list(); if(paths != null && paths.length > 0){ Optional yearPath = Arrays.stream(paths).filter(p -> p.contains(year)).findFirst(); if (yearPath.isPresent()){ return file2Str(HOLIDAY_NOTICES_FILE_PATH + yearPath.get()); } } return null; } private static LocalDate parseDate(String year, String month, String day) { String dateStr = year + "-" + month + "-" + day; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d"); return LocalDate.parse(dateStr, formatter); } public static void str2File(String str, String filePath, String fileName, String fileSuffix) throws IOException { File file = new File(filePath + fileName + fileSuffix); if (!file.getParentFile().exists()) { boolean created = file.getParentFile().mkdirs(); if (!created) { throw new IOException("文件路径创建失败"); } } try (FileWriter writer = new FileWriter(file)) { writer.write(str); } catch (IOException e) { e.printStackTrace(); } } private static String file2Str(String filePath) { File file = new File(filePath); try (FileReader reader = new FileReader(file)) { char[] buffer = new char[(int) file.length()]; reader.read(buffer); return new String(buffer); } catch (IOException e) { e.printStackTrace(); } return null; } private static final Pattern PATTERN = Pattern.compile("[^\\d]"); private static String getDigit(String content, String targetStr) { if(!content.contains(targetStr)){ return null; } content = content.substring(0, content.indexOf(targetStr)); StringBuffer sb = new StringBuffer(content); content = sb.reverse().toString(); //使用正则表达式匹配第一个非数字 Matcher matcher = PATTERN.matcher(content); if (matcher.find()) { content = content.substring(0, matcher.start()); sb = new StringBuffer(content); return sb.reverse().toString(); } //是否为数字 if(NumberUtil.isNumber(content)){ return new StringBuffer(content).reverse().toString(); } return null; }}
来源地址:https://blog.csdn.net/wshzfansjk/article/details/131513787
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341