基于Java代码实现判断春节、端午节、中秋节等法定节假日的方法
作者:风一样的码农
这篇文章主要介绍了基于Java代码实现判断春节、端午节、中秋节等法定节假日的方法 的相关资料,需要的朋友可以参考下
一、前言
最近工作上遇到一个问题,后端有一个定时任务,需要用JAVA每天判断法定节假日、周末放假,上班等情况,其实想单独通过逻辑什么的去判断中国法定节假日的放假情况,基本不可能,因为国家每一年的假期可能不一样,是人为设定的;
所以只能依靠其它手段,能想到的比较靠谱的如下:
1.网络接口:有些数据服务商会提供,要么是收钱的,要么是次数限制,等等各种问题,效果不理想,可控性差,我也没试过,如:
https://www.juhe.cn/docs/api/id/177/aid/601
或者
http://apistore.baidu.com/apiworks/servicedetail/1116.html
2.在线解析网页信息,获取节假日情况:严重依赖被解析的网站网页,所以在选取网站的时候,要找稍微靠谱点的;
3.根据国家规定的法定节假日放假情况,每年录入系统,这种如果客户不怕麻烦的话。还是比较靠谱的;
本Demo将选择第二种来实现;
二、使用htmlunit在线解析网页信息,获取节假日情况
一开始是使用jsoup去解析网页的,效果不理想,如果网页是动态生成的时候,用jsoup遇到了各种问题,所以改成了htmlunit,总得来说htmlunit还是很强大的,能够模拟浏览器运行,被誉为java浏览器的开源实现;
首先去官网下载相关jar包,以及阅读相关文档:
http://htmlunit.sourceforge.net/
我这里解析的网页是360的万年历:
日历界面如下:
被解析的 HTML格式如下:
实现步骤:
1、加载页面;
2、循环等待页面加载完成(可能会有一些动态页面,是用javascript生成);
3、根据网页格式解析html内容,并提取关键信息存入封装好的对象;
注意点:
1、难点在于判断是否休假及假期类型,由于原页面并没有标明每一天的假期类型,所以这里的逻辑要自己去实现,详情参考代码;
2、之所以有个静态latestVocationName变量,是防止出现以下情况(出现该情况的概率极低;PS:方法要每天调用一次,该变量才生效):
代码实现:
定义一个中国日期类:
1 package com.pichen.tools.getDate;
2 import java.util.Date;
3 public class ChinaDate {
4 /**
5 * 公历时间
6 */
7 private Date solarDate;
8
9 /**
10 * 农历日
11 */
12 private String lunar;
13
14 /**
15 * 公历日
16 */
17 private String solar;
18
19 /**
20 * 是否是 休
21 */
22 private boolean isVacation = false;
23
24 /**
25 * 如果是 休情况下的假期名字
26 */
27 private String VacationName = "非假期";
28
29 /**
30 * 是否是 班
31 */
32 private boolean isWorkFlag = false;
33 private boolean isSaturday = false;
34 private boolean isSunday = false;
35
36 /**
37 * @return the solarDate
38 */
39 public Date getSolarDate() {
40 return solarDate;
41 }
42
43 /**
44 * @param solarDate the solarDate to set
45 */
46 public void setSolarDate(Date solarDate) {
47 this.solarDate = solarDate;
48 }
49
50 /**
51 * @return the lunar
52 */
53 public String getLunar() {
54 return lunar;
55 }
56
57 /**
58 * @param lunar the lunar to set
59 */
60 public void setLunar(String lunar) {
61 this.lunar = lunar;
62 }
63
64 /**
65 * @return the solar
66 */
67 public String getSolar() {
68 return solar;
69 }
70
71 /**
72 * @param solar the solar to set
73 */
74 public void setSolar(String solar) {
75 this.solar = solar;
76 }
77
78 /**
79 * @return the isVacation
80 */
81 public boolean isVacation() {
82 return isVacation;
83 }
84 /**
85 * @param isVacation the isVacation to set
86 */
87 public void setVacation(boolean isVacation) {
88 this.isVacation = isVacation;
89 }
90
91 /**
92 * @return the vacationName
93 */
94 public String getVacationName() {
95 return VacationName;
96 }
97
98 /**
99 * @param vacationName the vacationName to set
100 */
101 public void setVacationName(String vacationName) {
102 VacationName = vacationName;
103 }
104
105 /**
106 * @return the isWorkFlag
107 */
108 public boolean isWorkFlag() {
109 return isWorkFlag;
110 }
111
112 /**
113 * @param isWorkFlag the isWorkFlag to set
114 */
115 public void setWorkFlag(boolean isWorkFlag) {
116 this.isWorkFlag = isWorkFlag;
117 }
118
119 /**
120 * @return the isSaturday
121 */
122 public boolean isSaturday() {
123 return isSaturday;
124 }
125
126 /**
127 * @param isSaturday the isSaturday to set
128 */
129 public void setSaturday(boolean isSaturday) {
130 this.isSaturday = isSaturday;
131 }
132
133 /**
134 * @return the isSunday
135 */
136 public boolean isSunday() {
137 return isSunday;
138 }
139
140 /**
141 * @param isSunday the isSunday to set
142 */
143 public void setSunday(boolean isSunday) {
144 this.isSunday = isSunday;
145 }
146 }
解析网页,并调用demo,打印本月详情,和当天详情:
1 package com.pichen.tools.getDate;
2 import java.io.IOException;
3 import java.net.MalformedURLException;
4 import java.text.DateFormat;
5 import java.text.ParseException;
6 import java.text.SimpleDateFormat;
7 import java.util.ArrayList;
8 import java.util.Date;
9 import java.util.List;
10 import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
11 import com.gargoylesoftware.htmlunit.WebClient;
12 import com.gargoylesoftware.htmlunit.html.DomNodeList;
13 import com.gargoylesoftware.htmlunit.html.HtmlElement;
14 import com.gargoylesoftware.htmlunit.html.HtmlPage;
15
16 public class Main {
17 private static String latestVocationName="";
18 public String getVocationName(DomNodeList<HtmlElement> htmlElements, String date) throws ParseException{
19 String rst = "";
20 boolean pastTimeFlag = false;
21 DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
22 Date paramDate = dateFormat.parse(date);
23 if(new Date().getTime() >= paramDate.getTime()){
24 pastTimeFlag = true;
25 }
26
27 //first step //jugde if can get vocation name from html page
28 for(int i = 0; i < htmlElements.size(); i++){
29 HtmlElement element = htmlElements.get(i);
30 if(element.getAttribute("class").indexOf("vacation")!=-1){
31 boolean hitFlag = false;
32 String voationName = "";
33
34 for(; i < htmlElements.size(); i++){
35 HtmlElement elementTmp = htmlElements.get(i);
36 String liDate = elementTmp.getAttribute("date");
37 List<HtmlElement> lunar = elementTmp.getElementsByAttribute("span", "class", "lunar");
38 String lanarText = lunar.get(0).asText();
39 if(lanarText.equals("元旦")){
40 voationName = "元旦";
41 }else if(lanarText.equals("除夕")||lanarText.equals("春节")){
42 voationName = "春节";
43 }else if(lanarText.equals("清明")){
44 voationName = "清明";
45 }else if(lanarText.equals("国际劳动节")){
46 voationName = "国际劳动节";
47 }else if(lanarText.equals("端午节")){
48 voationName = "端午节";
49 }else if(lanarText.equals("中秋节")){
50 voationName = "中秋节";
51 }else if(lanarText.equals("国庆节")){
52 voationName = "国庆节";
53 }
54
55 if(liDate.equals(date)){
56 hitFlag = true;
57 }
58 if(elementTmp.getAttribute("class").indexOf("vacation")==-1){
59 break;
60 }
61 }
62
63 if(hitFlag == true && !voationName.equals("")){
64 rst = voationName;
65 break;
66 }
67 }else{
68 continue;
69 }
70 }
71
72 //if first step fail(rarely), get from the latest Vocation name
73 if(rst.equals("")){
74 System.out.println("warning: fail to get vocation name from html page.");
75 //you can judge by some simple rule
76 //from the latest Vocation name
77 rst = Main.latestVocationName;
78 }else if(pastTimeFlag == true){
79 //更新《当前时间,且最近一次的可见的假期名
80 Main.latestVocationName = rst;
81 }
82 return rst;
83 }//end method
84
85 public List<ChinaDate> getCurrentDateInfo(){
86 WebClient webClient = null;
87 List<ChinaDate> dateList = null;
88
89 try{
90 DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
91 dateList = new ArrayList<ChinaDate>();
92 webClient = new WebClient();
93 HtmlPage page = webClient.getPage("http://hao.360.cn/rili/");
94 //最大等待60秒
95 for(int k = 0; k < 60; k++){
96 if(!page.getElementById("M-dates").asText().equals("")) break;
97 Thread.sleep(1000);
98 }
99 //睡了8秒,等待页面加载完成...,有时候,页面可能获取不到,不稳定()
100 //Thread.sleep(8000);
101 DomNodeList<HtmlElement> htmlElements = page.getElementById("M-dates").getElementsByTagName("li");
102 //System.out.println(htmlElements.size());
103 for(HtmlElement element : htmlElements){
104 ChinaDate chinaDate = new ChinaDate();
105 List<HtmlElement> lunar = element.getElementsByAttribute("span", "class", "lunar");
106 List<HtmlElement> solar = element.getElementsByAttribute("div", "class", "solar");
107 chinaDate.setLunar(lunar.get(0).asText());
108 chinaDate.setSolar(solar.get(0).asText());
109 chinaDate.setSolarDate(dateFormat.parse(element.getAttribute("date")));
110
111 if(element.getAttribute("class").indexOf("vacation")!=-1){
112 chinaDate.setVacation(true);
113 chinaDate.setVacationName(this.getVocationName(htmlElements, element.getAttribute("date")));
114 }
115
116 if(element.getAttribute("class").indexOf("weekend")!=-1 &&
117 element.getAttribute("class").indexOf("last")==-1){
118 chinaDate.setSaturday(true);
119 }
120
121 if(element.getAttribute("class").indexOf("last weekend")!=-1){
122 chinaDate.setSunday(true);
123 }
124
125 if(element.getAttribute("class").indexOf("work")!=-1){
126 chinaDate.setWorkFlag(true);
127 }else if(chinaDate.isSaturday() == false &&
128 chinaDate.isSunday() == false &&
129 chinaDate.isVacation() == false ){
130 chinaDate.setWorkFlag(true);
131 }else{
132 chinaDate.setWorkFlag(false);
133 }
134
135 dateList.add(chinaDate);
136 }
137 }catch(Exception e){
138 e.printStackTrace();
139 System.out.println("get date from http://hao.360.cn/rili/ error~");
140 }finally{
141 webClient.close();
142 }
143
144 return dateList;
145 }
146
147 public ChinaDate getTodayInfo(){
148 List<ChinaDate> dateList = this.getCurrentDateInfo();
149 DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
150 for(ChinaDate date: dateList){
151 if(dateFormat.format(date.getSolarDate()).equals(dateFormat.format(new Date()))){
152 return date;
153 }
154 }
155 return new ChinaDate();
156 }
157
158 public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
159 List<ChinaDate> dateList = new Main().getCurrentDateInfo();
160 ChinaDate today = new Main().getTodayInfo();
161 DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
162 System.out.println("本月详情:");
163 for(ChinaDate date: dateList){
164 System.out.println(dateFormat.format(date.getSolarDate()) + " " + date.getVacationName());
165 }
166 System.out.println("------------------------------------------------------------------------");
167 System.out.println("今日详情:");
168 System.out.println("日期:" + today.getSolarDate());
169 System.out.println("农历:"+today.getLunar());
170 System.out.println("公历:"+today.getSolar());
171 System.out.println("假期名:"+today.getVacationName());
172 System.out.println("是否周六:"+today.isSaturday());
173 System.out.println("是否周日:"+today.isSunday());
174 System.out.println("是否休假:"+today.isVacation());
175 System.out.println("是否工作日:"+today.isWorkFlag());
176 System.out.println("已发生的最近一次假期:" + Main.latestVocationName);
177 }
178 }
运行程序,结果正确: