|
@@ -1,324 +1,324 @@
|
|
-package com.ruoyi.common.utils;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-import com.ruoyi.common.utils.http.HttpUtils;
|
|
|
|
-import okhttp3.*;
|
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
|
-import org.apache.commons.lang3.math.NumberUtils;
|
|
|
|
-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;
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * @Author: tjf
|
|
|
|
- * @Date: 2023/11/2 9:20
|
|
|
|
- * @Describe:
|
|
|
|
- */
|
|
|
|
-public class ChinaHolidaysUtils {
|
|
|
|
- /**
|
|
|
|
- * 国务院发布的节假日安排的通知 保存的文件路径
|
|
|
|
- */
|
|
|
|
- private static final String HOLIDAY_NOTICES_FILE_PATH = ChinaHolidaysUtils.class.getResource("/").getPath()+"国务院发布的节假日安排的通知/";
|
|
|
|
- /**
|
|
|
|
- * 国务院文件搜索地址
|
|
|
|
- */
|
|
|
|
- private static final String GOV_URL = "https://sousuo.www.gov.cn/sousuo/search.shtml?code=17da70961a7&dataTypeId=107&";
|
|
|
|
-
|
|
|
|
- private static Set<String> publicHolidays = new ConcurrentSkipListSet<>();
|
|
|
|
- private static Set<String> oxenHorseDays = new ConcurrentSkipListSet<>();
|
|
|
|
-
|
|
|
|
- public static void main(String[] args) {
|
|
|
|
- try {
|
|
|
|
- //System.out.println(isOxenHorseDays("2023-12-30"));
|
|
|
|
- System.out.println(isPublicHolidays("2024-12-30"));
|
|
|
|
- } catch (IOException e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
- }
|
|
|
|
- System.out.println("publicHolidays: " + publicHolidays);
|
|
|
|
- System.out.println("oxenHorseDays: " + oxenHorseDays);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 是否为调休补班日
|
|
|
|
- * @param localDate
|
|
|
|
- * @return
|
|
|
|
- * @throws IOException
|
|
|
|
- */
|
|
|
|
- public static boolean isOxenHorseDays(String localDate) throws IOException {
|
|
|
|
- if(oxenHorseDays.isEmpty()){
|
|
|
|
- getDays(localDate, publicHolidays, oxenHorseDays);
|
|
|
|
- }
|
|
|
|
- return oxenHorseDays.contains(localDate);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 是否为法定节假日
|
|
|
|
- * @param localDate
|
|
|
|
- * @return
|
|
|
|
- * @throws IOException
|
|
|
|
- */
|
|
|
|
- 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<String> publicHolidays, Set<String> 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("上班")) {
|
|
|
|
- String t = sentence.split("上班")[0];
|
|
|
|
- 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());
|
|
|
|
- }
|
|
|
|
- }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);
|
|
|
|
- oxenHorseDays.add(date.toString());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 模拟人为操作的参数
|
|
|
|
- * @param url
|
|
|
|
- */
|
|
|
|
- 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,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
|
|
|
|
- .header("Host", "www.gov.cn")
|
|
|
|
- .header("Referer", "http://sousuo.www.gov.cn/")
|
|
|
|
-// .header("Accept-Encoding", "gzip, deflate, br") 造成乱码问题
|
|
|
|
- .header("Accept-Language", "zh-CN,zh;q=0.9")
|
|
|
|
- .header("Cache-Control", "max-age=0")
|
|
|
|
- .header("Connection", "keep-alive")
|
|
|
|
- .header("Sec-Fetch-Dest", "document")
|
|
|
|
- .header("Sec-Fetch-Mode", "navigate")
|
|
|
|
- .header("Sec-Fetch-Site", "cross-site")
|
|
|
|
- .header("Sec-Fetch-User", "?1")
|
|
|
|
- .header("Upgrade-Insecure-Requests", "1")
|
|
|
|
- .header("sec-ch-ua", "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"")
|
|
|
|
- .header("sec-ch-ua-mobile", "?0")
|
|
|
|
- .header("sec-ch-ua-platform", "Windows");
|
|
|
|
- return builder.url(url).build();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * http get请求
|
|
|
|
- * @param client
|
|
|
|
- * @param url
|
|
|
|
- * @return
|
|
|
|
- * @throws IOException
|
|
|
|
- */
|
|
|
|
- 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;
|
|
|
|
- }
|
|
|
|
- /**
|
|
|
|
- * 通过http获取国务院发布xxxx年的节假日安排的通知
|
|
|
|
- * @return
|
|
|
|
- * @throws IOException
|
|
|
|
- */
|
|
|
|
- private static String getHtmlByHttp(String year) throws IOException {
|
|
|
|
- OkHttpClient client = new OkHttpClient();
|
|
|
|
- String searchWord ="searchWord=" + year + "节假日";
|
|
|
|
- String html = httpGet(client, GOV_URL+searchWord);
|
|
|
|
- Document doc = Jsoup.parse(html);
|
|
|
|
- Elements resList = doc.select("li.res-list");
|
|
|
|
- if (!resList.isEmpty()) {
|
|
|
|
- Optional<Element> 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;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 先通过缓存节假日通知的指定目录中获取 当年的 节假日通知文件
|
|
|
|
- * @param year
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private static String getHtmlByCacheFiles(String year) {
|
|
|
|
- String[] paths = new File(HOLIDAY_NOTICES_FILE_PATH).list();
|
|
|
|
- if(paths != null && paths.length > 0){
|
|
|
|
- Optional<String> yearPath = Arrays.stream(paths).filter(p -> p.contains(year)).findFirst();
|
|
|
|
- if (yearPath.isPresent()){
|
|
|
|
- return file2Str(HOLIDAY_NOTICES_FILE_PATH + yearPath.get());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 根据年月日字符转为 yyyy-M-d 格式的LocalDate
|
|
|
|
- * @param year
|
|
|
|
- * @param month
|
|
|
|
- * @param day
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- 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);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 将字符串内容转为文件存到指定路径下
|
|
|
|
- * @param str
|
|
|
|
- * @param filePath
|
|
|
|
- */
|
|
|
|
- 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();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 将指定路径的文件转为字符串
|
|
|
|
- * @param filePath
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- 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(NumberUtils.isCreatable(content)){
|
|
|
|
- return new StringBuffer(content).reverse().toString();
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-}
|
|
|
|
|
|
+//package com.ruoyi.common.utils;
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+//import com.ruoyi.common.utils.http.HttpUtils;
|
|
|
|
+//import okhttp3.*;
|
|
|
|
+//import org.apache.commons.lang3.StringUtils;
|
|
|
|
+//import org.apache.commons.lang3.math.NumberUtils;
|
|
|
|
+//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;
|
|
|
|
+//
|
|
|
|
+///**
|
|
|
|
+// * @Author: tjf
|
|
|
|
+// * @Date: 2023/11/2 9:20
|
|
|
|
+// * @Describe:
|
|
|
|
+// */
|
|
|
|
+//public class ChinaHolidaysUtils {
|
|
|
|
+// /**
|
|
|
|
+// * 国务院发布的节假日安排的通知 保存的文件路径
|
|
|
|
+// */
|
|
|
|
+// private static final String HOLIDAY_NOTICES_FILE_PATH = ChinaHolidaysUtils.class.getResource("/").getPath()+"国务院发布的节假日安排的通知/";
|
|
|
|
+// /**
|
|
|
|
+// * 国务院文件搜索地址
|
|
|
|
+// */
|
|
|
|
+// private static final String GOV_URL = "https://sousuo.www.gov.cn/sousuo/search.shtml?code=17da70961a7&dataTypeId=107&";
|
|
|
|
+//
|
|
|
|
+// private static Set<String> publicHolidays = new ConcurrentSkipListSet<>();
|
|
|
|
+// private static Set<String> oxenHorseDays = new ConcurrentSkipListSet<>();
|
|
|
|
+//
|
|
|
|
+// public static void main(String[] args) {
|
|
|
|
+// try {
|
|
|
|
+// //System.out.println(isOxenHorseDays("2023-12-30"));
|
|
|
|
+// System.out.println(isPublicHolidays("2024-12-30"));
|
|
|
|
+// } catch (IOException e) {
|
|
|
|
+// e.printStackTrace();
|
|
|
|
+// }
|
|
|
|
+// System.out.println("publicHolidays: " + publicHolidays);
|
|
|
|
+// System.out.println("oxenHorseDays: " + oxenHorseDays);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 是否为调休补班日
|
|
|
|
+// * @param localDate
|
|
|
|
+// * @return
|
|
|
|
+// * @throws IOException
|
|
|
|
+// */
|
|
|
|
+// public static boolean isOxenHorseDays(String localDate) throws IOException {
|
|
|
|
+// if(oxenHorseDays.isEmpty()){
|
|
|
|
+// getDays(localDate, publicHolidays, oxenHorseDays);
|
|
|
|
+// }
|
|
|
|
+// return oxenHorseDays.contains(localDate);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 是否为法定节假日
|
|
|
|
+// * @param localDate
|
|
|
|
+// * @return
|
|
|
|
+// * @throws IOException
|
|
|
|
+// */
|
|
|
|
+// 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<String> publicHolidays, Set<String> 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("上班")) {
|
|
|
|
+// String t = sentence.split("上班")[0];
|
|
|
|
+// 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());
|
|
|
|
+// }
|
|
|
|
+// }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);
|
|
|
|
+// oxenHorseDays.add(date.toString());
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 模拟人为操作的参数
|
|
|
|
+// * @param url
|
|
|
|
+// */
|
|
|
|
+// private static Request getRequestSetUnifiedHead(String url){
|
|
|
|
+// 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,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
|
|
|
|
+// .header("Host", "www.gov.cn")
|
|
|
|
+// .header("Referer", "http://sousuo.www.gov.cn/")
|
|
|
|
+//// .header("Accept-Encoding", "gzip, deflate, br") 造成乱码问题
|
|
|
|
+// .header("Accept-Language", "zh-CN,zh;q=0.9")
|
|
|
|
+// .header("Cache-Control", "max-age=0")
|
|
|
|
+// .header("Connection", "keep-alive")
|
|
|
|
+// .header("Sec-Fetch-Dest", "document")
|
|
|
|
+// .header("Sec-Fetch-Mode", "navigate")
|
|
|
|
+// .header("Sec-Fetch-Site", "cross-site")
|
|
|
|
+// .header("Sec-Fetch-User", "?1")
|
|
|
|
+// .header("Upgrade-Insecure-Requests", "1")
|
|
|
|
+// .header("sec-ch-ua", "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"")
|
|
|
|
+// .header("sec-ch-ua-mobile", "?0")
|
|
|
|
+// .header("sec-ch-ua-platform", "Windows");
|
|
|
|
+// return builder.url(url).build();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * http get请求
|
|
|
|
+// * @param client
|
|
|
|
+// * @param url
|
|
|
|
+// * @return
|
|
|
|
+// * @throws IOException
|
|
|
|
+// */
|
|
|
|
+// 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;
|
|
|
|
+// }
|
|
|
|
+// /**
|
|
|
|
+// * 通过http获取国务院发布xxxx年的节假日安排的通知
|
|
|
|
+// * @return
|
|
|
|
+// * @throws IOException
|
|
|
|
+// */
|
|
|
|
+// private static String getHtmlByHttp(String year) throws IOException {
|
|
|
|
+// OkHttpClient client = new OkHttpClient();
|
|
|
|
+// String searchWord ="searchWord=" + year + "节假日";
|
|
|
|
+// String html = httpGet(client, GOV_URL+searchWord);
|
|
|
|
+// Document doc = Jsoup.parse(html);
|
|
|
|
+// Elements resList = doc.select("li.res-list");
|
|
|
|
+// if (!resList.isEmpty()) {
|
|
|
|
+// Optional<Element> 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;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 先通过缓存节假日通知的指定目录中获取 当年的 节假日通知文件
|
|
|
|
+// * @param year
|
|
|
|
+// * @return
|
|
|
|
+// */
|
|
|
|
+// private static String getHtmlByCacheFiles(String year) {
|
|
|
|
+// String[] paths = new File(HOLIDAY_NOTICES_FILE_PATH).list();
|
|
|
|
+// if(paths != null && paths.length > 0){
|
|
|
|
+// Optional<String> yearPath = Arrays.stream(paths).filter(p -> p.contains(year)).findFirst();
|
|
|
|
+// if (yearPath.isPresent()){
|
|
|
|
+// return file2Str(HOLIDAY_NOTICES_FILE_PATH + yearPath.get());
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 根据年月日字符转为 yyyy-M-d 格式的LocalDate
|
|
|
|
+// * @param year
|
|
|
|
+// * @param month
|
|
|
|
+// * @param day
|
|
|
|
+// * @return
|
|
|
|
+// */
|
|
|
|
+// 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);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 将字符串内容转为文件存到指定路径下
|
|
|
|
+// * @param str
|
|
|
|
+// * @param filePath
|
|
|
|
+// */
|
|
|
|
+// 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();
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 将指定路径的文件转为字符串
|
|
|
|
+// * @param filePath
|
|
|
|
+// * @return
|
|
|
|
+// */
|
|
|
|
+// 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(NumberUtils.isCreatable(content)){
|
|
|
|
+// return new StringBuffer(content).reverse().toString();
|
|
|
|
+// }
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+//}
|