java工作日和节假日判断

/ Java / 没有评论 / 2330浏览

java工作日和节假日判断

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

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

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

工程结构: 1

建表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;12345

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();
    }
}

效果: 2

3

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