java工作日和节假日判断

Posted Lovnx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java工作日和节假日判断相关的知识,希望对你有一定的参考价值。

最近公司有个业务需要判断工作日,但是每年的节假日不一样,且不说周末、法定节假日这些,有些公司还有自己的节假日,这样就很难写出一劳永逸的方法来实现了。
其实我们可以借助数据库来实现这个功能,可以把每年的节假日或者工作日存储到数据库中,再用sql查询出两个日期之间的节假日或者工作日来,计算数量,就可以实现了,后期也方便维护,可以根据需要手动添加一些特殊节假日。

这次需要用到百度API集市的一款接口,检查具体日期是否为节假日,工作日对应结果为 0, 休息日对应结果为 1, 节假日对应的结果为 2;
支持 2009 年起至最新 中国法定节假日,以国务院发布的公告为准,随时调整及增加;
参数可以以 GET 或 POST 方式传递,以 JSON 格式返回结果。
JSON返回示例 :“20130101”:2,”20130103”:2,”20130105”:”0”,”20130201”:”0”
由于API响应速度比较慢,采用数据库来存储节假日或者工作日,这样调用就快很多了,只需要初始化插入数据就行了。

下面是一个具体实例:(以工作日计算举例,数据库用的mysql)

工程结构:

建表sql:

CREATE TABLE `workday` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `workday` DATE DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

DBConn:

import java.sql.Connection;  
import java.sql.DriverManager;  
import java.sql.PreparedStatement;  
import java.sql.SQLException;  

public class DBConn   
    public static final String url = "jdbc:mysql://localhost:3306/test";  
    public static final String name = "com.mysql.jdbc.Driver";  
    public static final String user = "root";  
    public static final String password = "1992115";  

    Connection conn = null;
    public PreparedStatement pst = null;  

    public Connection Conn()   
        try   
            Class.forName(name);
            conn = DriverManager.getConnection(url, user, password);
         catch (Exception e)   
            e.printStackTrace();  
          
        return conn;
      

    public void close()   
        try   
            this.conn.close();  
         catch (SQLException e)   
            e.printStackTrace();  
          
      
  

DateAPI(核心类):

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 
 * @ClassName:DateAPI
 * @Description:当前年 的节假日 查询 工具类
 * @author Lovnx
 * @qq 930999349
 * @date 2016-8-5 上午10:08:44
 */

public class DateAPI 

    public List<String> getWorkDays()
        throws Exception 
        List<String> list = new ArrayList<String>();
        Calendar a = Calendar.getInstance();
        String httpUrl = "http://apis.baidu.com/xiaogg/holiday/holiday";
        String t = a.get(Calendar.YEAR) + "0101";// 开始的日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat sdfDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();// 开始日期,并要累积加 一
        Calendar calendar2 = Calendar.getInstance();// 结束的日期
        Date time = sdf.parse(t);
        calendar.setTime(time);
        calendar2.setTime(time);
        calendar2.add(Calendar.YEAR, 1);// 加上一年的后的日期
        Date first = calendar.getTime();
        Date next = calendar2.getTime();
        while (first.getTime() < next.getTime())  // 判断是否是节假日
            String fdate = "d=" + sdf.format(first.getTime());
            String jsonResult = request(httpUrl, fdate);
            // 判断是否是节假日
            if ("0".equals(jsonResult.trim())) 
                list.add(sdfDateFormat.format(first.getTime()));
            
            calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
            first = calendar.getTime(); // 这个时间就是日期往后推一天的结果
            calendar.getTime();
        
        return list;
    

    /**
     * @param urlAll :请求接口
     * @param httpArg :参数
     * @return 返回结果
     */
    public String request(String httpUrl, String httpArg) 
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        httpUrl = httpUrl + "?" + httpArg;
        try 
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setRequestMethod("GET");
            // 填入apikey到HTTP header
            connection.setRequestProperty("apikey", "abfa5282a89706affd2e4ad6651c9648");
            connection.connect();
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) 
                sbf.append(strRead);
                sbf.append("\\r\\n");
            
            reader.close();
            result = sbf.toString();
         catch (Exception e) 
            e.printStackTrace();
        
        return result;
    

DAO:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DAO 

      public int workdayAdd(Connection con,String date)
                throws SQLException
              
                String sql = "insert into workday values (null,?)";
                PreparedStatement pstmt = con.prepareStatement(sql);
                pstmt.setString(1, date);
                return pstmt.executeUpdate();
              

      public ResultSet countWorkday(Connection con, String beginDay,String endDay) throws Exception 
            StringBuffer sb = new StringBuffer("SELECT COUNT(w.id) - 2 FROM workday w WHERE w.workday BETWEEN '"+beginDay+"' AND '"+endDay+"'");
            PreparedStatement pstmt = con.prepareStatement(sb.toString());
            return pstmt.executeQuery();
          

test:

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.List;


public class test 

    public static void main(String[] args) throws Exception 
        DBConn dbConn = new DBConn();
        Connection con = dbConn.Conn();
        DAO dao = new DAO();
        DateAPI dateAPI = new DateAPI();

        //向工作日表插入数据,初始化时打开注释
        /*List<String> list= dateAPI.getWorkDays();
        for (String string : list) 
            dao.workdayAdd(con, string);
        */

        ResultSet rst = dao.countWorkday(con, "2016-1-4", "2016-1-7");
        if (rst.next()) 
            System.out.println("中间间隔工作日天数为:"+rst.getInt(1));
        

        dbConn.close();
    

效果:

建议:
1、可以设置Spring定时任务每年跑一次,数据更准确。
2、可后期自行添加节假日。

以上是关于java工作日和节假日判断的主要内容,如果未能解决你的问题,请参考以下文章

JAVA判断当前日期是节假日还是工作日

java 获取n个工作日后的日期(包含法定节假日双休日节后补班)

java判断股市是不是休市

判断日期是否为法定节假日的API接口与示例函数

春节三天法定假日是哪几天

怎么从excel日期中找到法定节假日?