基于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的万年历:

http://hao.360.cn/rili/

日历界面如下:

Java 如何判断当前时间是否是假日 java如何判断节假日_java

Java 如何判断当前时间是否是假日 java如何判断节假日_java_02

被解析的 HTML格式如下:

Java 如何判断当前时间是否是假日 java如何判断节假日_html_03

实现步骤:

1、加载页面;

2、循环等待页面加载完成(可能会有一些动态页面,是用javascript生成);

3、根据网页格式解析html内容,并提取关键信息存入封装好的对象;

注意点:

1、难点在于判断是否休假及假期类型,由于原页面并没有标明每一天的假期类型,所以这里的逻辑要自己去实现,详情参考代码;

2、之所以有个静态latestVocationName变量,是防止出现以下情况(出现该情况的概率极低;PS:方法要每天调用一次,该变量才生效):

Java 如何判断当前时间是否是假日 java如何判断节假日_List_04

代码实现:

定义一个中国日期类:

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 }

 


运行程序,结果正确:

Java 如何判断当前时间是否是假日 java如何判断节假日_Java 如何判断当前时间是否是假日_05