记录:判断日期是工作日、休息日或法定休假日

RT:记录工作中客户提出的新需求,分辨日期是否是节假日与工作日,主要实现过程比较简单,通过爬虫获取百度日历数据接口,具体接口地址在下方代码中已经写明,调用接口判断日期即可,其中第一个参数为年份,第二个参数为固定值6018,具体实现代码如下:

package com.wly.util;

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

import com.alibaba.fastjson.JSONArray;
import com.wly.entity.CalendayEntity;

public class CalendayUtil {
	
	// 百度api接口url地址
	private static String baiduApiUrl = "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=%s&resource_id=%s";
	
	// 百度api查询resource_id字段值
	private static String resource_id = "6018";
	
	// 查询的年份
	private static int search_year = 0;
	
	// 保存节假日数据
	private static String festivalStr = null;
	
	// 用于保存上一次的日期,当日期更新后重新抓取百度日历接口数据
	private static String lastDate = null;
	
	// 将日期字符格式化为百度API传递的日期字符 如: 2017-10-01 --> 2017-10-1
	private SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-d");

	// 设置单例模式
	private static CalendayUtil calendayUtil = null;

	private CalendayUtil() { }

	public static CalendayUtil getInstance() {
		if (calendayUtil == null){
			calendayUtil = new CalendayUtil();
			// 首次创建对象时,保存当天日期
			lastDate = calendayUtil.dFormat.format(new Date());
		}
		// 当天时间与上次一查询时间不一至时,重新查询api数据
		if (!calendayUtil.dFormat.format(new Date()).equals(lastDate)){
			try {
				festivalStr = calendayUtil.sendReq(String.format(baiduApiUrl, search_year, resource_id));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return calendayUtil;
	}

	public String isFestival(Date date) throws IOException, ParseException {
		// 将日期字符格式化为百度API传递的日期字符 如: 2017-10-01 --> 2017-10-1
		return isFestival(dFormat.format(date));
	}

	public String isFestival(String dateStr) throws IOException, ParseException {
		Date dateParse = dFormat.parse(dateStr);
		// 获取当前查询日期的年份
		Calendar yearCalendar = Calendar.getInstance();
		yearCalendar.setTime(dateParse);
		// 未查询过数据
		if (search_year == 0){
			// 保存当前年份
			search_year = yearCalendar.getWeekYear();
			try {
				festivalStr = calendayUtil.sendReq(String.format(baiduApiUrl, search_year, resource_id));
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			// 查询过数据,如果年份不一样,则重新查询
			if (search_year != yearCalendar.getWeekYear()){
				search_year = yearCalendar.getWeekYear();
				try {
					festivalStr = calendayUtil.sendReq(String.format(baiduApiUrl, search_year, resource_id));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		// 将日期字符格式化为百度API传递的日期字符 如: 2017-10-01 --> 2017-10-1
		dateStr = dFormat.format(dateParse);
		String festivalStatus = null;
		// 判断今天是否是工作日 周末 还是节假日
		JSONArray jsonArr = JsonUtil.getjsonArray(festivalStr, "data");
		String holiday = JsonUtil.getString(jsonArr.getString(0), "holiday");
		if (null != holiday){
			List<CalendayEntity> calendarEntities = JsonUtil.jsonToBeanList(holiday, CalendayEntity.class);
			// 循环判断指定日期是否包含在节假日中
			for (CalendayEntity calendar : calendarEntities) {
				if (dateStr.equals(calendar.festival)) {
					// 法定节假日
					festivalStatus = dateStr + "是" + calendar.name + ",为法定节假日";
					break;
				}
				for (CalendayEntity.Festival festival : calendar.list) {
					if (dateStr.equals(festival.date)) {
						if ("1".equals(festival.status)) {
							// 法定节假日
							festivalStatus = dateStr + "是法定节假日";
							break;
						} else {
							// 非法定节假日
							festivalStatus = dateStr + "为法定节假日调班,备注:" + calendar.desc;
							break;
						}
					}
				}
			}
		}
		// 当前日期不包含在法定节假日中
		if (festivalStatus == null) {
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			Date parse = dateFormat.parse(dateStr);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(parse);
			// 判断日期是否为周末
			if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
				festivalStatus = dateStr + "为周末,休息日";
			} else {
				festivalStatus = dateStr + "为工作日";
			}
		}
		return festivalStatus;
	}

	/**
	 * 发送请求获取百度日历节假日数据
	 * @param reqUrl
	 * @return
	 * @throws  
	 * @throws IOException
	 */
	public String sendReq(String reqUrl) throws IOException {
		// reqUrl = String.format(reqUrl, dateStr);
		StringBuilder result = new StringBuilder();
		URL url = new URL(reqUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(10000);
		conn.setReadTimeout(10000);
		conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		// 连接服务器
		conn.connect();
		try(BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"))){
			String line = null;
			while ((line = in.readLine()) != null) {
				result.append(line);
			}
		}
		return result.toString();
	}
	
}

以下是实体类:

package com.wly.entity;
import java.util.List;

public class CalendayEntity {
	// 节日
	public String festival;
	// 节日名称
	public String name;
	// 节假日列表,状态为1表示节假日,状态为2表示节假日前后调整工作日
	public List<Festival> list;
	// 节假日备注
	public String desc;
	
	public class Festival {
		// 日期,字符串格式如:"2017-10-01"
		public String date;
		// 假日状态
		public String status;
	}
}

测试代码如下:

package com.wly.test;

import java.io.IOException;
import java.text.ParseException;

import com.wly.util.CalendayUtil;

public class Main {
	public static void main(String[] args) {
		try {
			// 判断日期是否工作日
			for (int i = 1; i <= 31; i ++){
				System.out.println(CalendayUtil.getInstance().isFestival("2017-10-" + i));
			}
		} catch (IOException | ParseException e) {
			e.printStackTrace();
		}
	}
}

输出结果:

2017-10-1是国庆节,为法定节假日

2017-10-2是法定节假日

2017-10-3是法定节假日

2017-10-4是中秋节,为法定节假日

...

2017-10-31为工作日

猜你喜欢

转载自my.oschina.net/u/3269106/blog/1581253