我们说的工作日和休息日一共有3个条件~
1.我们自己所在公司定义的特殊工作日和休息日(即便是公休日,但是公司可能会调休)
2.国家规定的节假日(元旦 春节 清明 端午 等等的)
3.公休日(周六,周天)
我们要具体计算某一天是否是工作日还是休息日,比较麻烦的就是获取国家规定的节假日的各种调休比较麻烦。以前有一个工作日插件~但是我看了一下他用的是一个服务接口来获取这个每年的节假日情况~那个接口服务商已经关闭了~另外网上其他的节假日服务商要么要收费,要么就不准(他会把免费的故意弄几个错误值在里面,我一共找了7个这种接口都是这样,要么要收钱,要么有错误)~所以我自己弄了一个方法~直接到国务院官网上去爬每年的节假日安排就好了~
PS:当然我们还有一个办法就是自己建个数据库,手动把这些数据输入进去也可以
不说了先看效果
然后 看代码
数据是保存在XML里面的所以有一个数据管理类
- package com.midas.plugin.func;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.List;
- import java.util.Set;
- import com.fr.base.FRContext;
- import com.fr.file.XMLFileManager;
- import com.fr.function.TODATE;
- import com.fr.general.GeneralContext;
- import com.fr.general.xml.GeneralXMLTools;
- import com.fr.json.JSONArray;
- import com.fr.json.JSONObject;
- import com.fr.stable.EncodeConstants;
- import com.fr.stable.EnvChangedListener;
- import com.fr.stable.xml.XMLPrintWriter;
- import com.fr.stable.xml.XMLableReader;
- public class DateRecord extends XMLFileManager {
-
- private JSONObject conf = JSONObject.create();
-
- public Date toDate( Object dtObj ){
- return (Date) new TODATE().run(new Object[]{dtObj});
- }
-
- public boolean isHoliday(Date dt){
- return isHoliday(dt,true,true);
- }
-
- public boolean isHoliday(Date dt, boolean useGov){
- return isHoliday(dt,useGov,true);
- }
-
- public boolean isHoliday(Date dt, boolean useGov, boolean useDef ){
- String year = getYear(dt);
- String dtStr = WorkDay.getDateStr(dt);
- //从自定义数据判断
- JSONObject custom = getCustom(year);
- int cr = isHoliday(custom,dtStr);
- if(cr!=-1){
- return cr == 1;
- }
- //从国务院数据判断
- if(useGov){
- JSONObject locale = getLocale(year);
- int lr = isHoliday(locale,dtStr);
- if(lr!=-1){
- return lr == 1;
- }
- }
- //直接判断是否是周末
- if(useDef){
- Calendar cal = Calendar.getInstance();
- cal.setTime(dt);
- int w = cal.get(Calendar.DAY_OF_WEEK);
- return w==1 || w==7;
- }
- return false;
- }
-
- public int getHolidayCount(Date start,Date end){
- int sy = Integer.parseInt(getYear(start));
- int ey = Integer.parseInt(getYear(end));
- int sdn = Integer.parseInt(WorkDay.getDateStr(start));
- int edn = Integer.parseInt(WorkDay.getDateStr(end));
- int count = 0;
- for(int i=sy;i<=ey;i++){
- JSONArray chJa = getCustom(i+"").optJSONArray("h");
- String ch = chJa.toString();
- String cw = getCustom(i+"").optJSONArray("w").toString();
- JSONArray dJa = getDefaultHoliday(i+"");
- for(int j=0;j<dJa.length();j++){
- int cDt = Integer.parseInt(dJa.optString(j));
- if( sdn <= cDt && cDt <= edn && cw.indexOf(cDt+"")==-1 && ch.indexOf(cDt+"")==-1 ){
- count++;
- }
- }
- JSONArray hJa = getLocale(i+"").optJSONArray("h");
- for(int j=0;j<hJa.length();j++){
- int cDt = Integer.parseInt(hJa.optString(j));
- if( sdn <= cDt && cDt <= edn && cw.indexOf(cDt+"")==-1 && ch.indexOf(cDt+"")==-1 ){
- count++;
- }
- }
- for(int j=0;j<chJa.length();j++){
- int cDt = Integer.parseInt(chJa.optString(j));
- if( sdn <= cDt && cDt <= edn ){
- count++;
- }
- }
- }
- return count;
- }
-
- /**
- * 生成一年内全部的周末假日
- * @param year
- */
- private JSONArray getDefaultHoliday(String year){
- JSONObject locale = this.getLocale(year);
- if(locale.has("d")){
- return locale.optJSONArray("d");
- }
- String hJa = locale.optJSONArray("h").toString();
- String wJa = locale.optJSONArray("w").toString();
- Date[] wkd = getFirstWKD(year);
- JSONArray dfthwkd = JSONArray.create();
- Date sd = wkd[wkd.length-1];
- if( wkd.length==2 ){
- String dStr = WorkDay.getDateStr(wkd[0]);
- if( wJa.indexOf(dStr)==-1 && hJa.indexOf(dStr)==-1 ){
- dfthwkd.put(dStr);
- }
- }
- Calendar cal = Calendar.getInstance();
- while( getYear(sd).equals(year) ){
- String dStr = WorkDay.getDateStr(sd);
- if( wJa.indexOf(dStr)==-1 && hJa.indexOf(dStr)==-1 ){
- dfthwkd.put(dStr);
- }
- cal.setTime(sd);
- cal.add(Calendar.DATE, 6);
- sd = cal.getTime();
- if( !getYear(sd).equals(year) ){
- break;
- }
- dStr = WorkDay.getDateStr(sd);
- if( wJa.indexOf(dStr)==-1 && hJa.indexOf(dStr)==-1 ){
- dfthwkd.put(dStr);
- }
- cal.setTime(sd);
- cal.add(Calendar.DATE, 1);
- sd = cal.getTime();
- }
- try{
- locale.put("d",dfthwkd);
- FRContext.getCurrentEnv().writeResource(this);
- }catch(Exception e){}
- return locale.optJSONArray("d");
- }
-
- /**
- * 获取某年的第一个周末
- * @param year
- * @return
- */
- private Date[] getFirstWKD(String year){
- Date[] rt = null;
- Calendar cal = Calendar.getInstance();
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
- try{
- Date firstDay = format.parse(year+"0101");
- cal.setTime(firstDay);
- int w = cal.get(Calendar.DAY_OF_WEEK);
- while( w!=1 && w!=7 ){
- cal.add(Calendar.DATE, 1);
- w = cal.get(Calendar.DAY_OF_WEEK);
- };
- if(w==7){
- rt = new Date[2];
- rt[0] = cal.getTime();
- cal.add(Calendar.DATE, 1);
- rt[1] = cal.getTime();
- }else if(w==1){
- rt = new Date[1];
- rt[0] = cal.getTime();
- }
- }catch(Exception e){}
- return rt;
- }
-
- private int isHoliday(JSONObject plan,String dtStr){
- String lh = plan.optJSONArray("h").toString();
- if(lh.indexOf(dtStr)!=-1){
- return 1;
- }
- String lw = plan.optJSONArray("w").toString();
- if(lw.indexOf(dtStr)!=-1){
- return 0;
- }
- return -1;
- }
-
- private String getYear(Date dt){
- SimpleDateFormat format = new SimpleDateFormat("yyyy");
- String dtStr = format.format(dt);
- return dtStr;
- }
- private JSONObject opt(String key){
- try{
- if(!conf.has(key)){
- conf.put(key, JSONObject.create());
- }
- }catch(Exception e){}
- return conf.optJSONObject(key);
- }
-
- private JSONObject getCustom(String year){
- JSONObject custom = opt("custom");
- if(!custom.has(year)){
- try{
- custom.put(year,JSONObject.create().put("h", JSONArray.create()).put("w", JSONArray.create()));
- }catch(Exception e){}
- }
- return custom.optJSONObject(year);
- }
-
- private JSONObject getLocale(String year){
- JSONObject locale = opt("locale");
- if(!locale.has(year)){
- loadWebHoliday( year );
- }
- return locale.optJSONObject(year);
- }
-
- private JSONObject loadWebHoliday( String year ){
- try{
- JSONObject result = JSONObject.create();
- List<String> wDateList = new ArrayList<String>();
- List<String> hDateList = new ArrayList<String>();
- //从国务院官网下载某一年的节假日安排情况
- WorkDay.loadHolidayPlanFromGov(year, wDateList, hDateList);
- JSONArray wJa = JSONArray.create();
- JSONArray hJa = JSONArray.create();
- for(String d : wDateList ){
- wJa.put(d);
- }
- for(String d : hDateList ){
- hJa.put(d);
- }
- result.put("w", wJa);
- result.put("h", hJa);
- conf.optJSONObject("locale").put(year, result);
- FRContext.getCurrentEnv().writeResource(this);
- }catch(Exception e){}
- return conf;
- }
-
- private static final long serialVersionUID = 4378324674935440870L;
- private static DateRecord SE = null;
-
- private DateRecord(){
- readXMLFile();
- }
-
- public synchronized static DateRecord getInstance(){
- if( null == SE ){
- SE = new DateRecord();
- }
- return SE;
- }
-
- static {
- GeneralContext.addEnvChangedListener(new EnvChangedListener() {
- public void envChanged() {
- DateRecord.envChanged();
- }
- });
- }
- private synchronized static void envChanged() {
- SE = null;
- }
-
- @Override
- public String fileName() {
- return "holiday.xml";
- }
- @Override
- public void writeXML(XMLPrintWriter writer) {
- writer.startTAG("Conf");
- writer.startTAG("Custom");
- try{
- Set<String> years = opt("custom").toMap().keySet();
- for(String year : years ){
- JSONObject yJo = opt("custom").optJSONObject(year);
- JSONArray hJa = yJo.optJSONArray("h");
- for(int i=0;i<hJa.length();i++){
- writer.startTAG("item").attr("dt", hJa.optString(i)).attr("type", "h").end();
- }
- JSONArray wJa = yJo.optJSONArray("w");
- for(int i=0;i<wJa.length();i++){
- writer.startTAG("item").attr("dt", wJa.optString(i)).attr("type", "w").end();
- }
- }
- }catch(Exception e){}
- writer.end();
-
- writer.startTAG("Locale");
- try{
- GeneralXMLTools.writeByteArray(writer, conf.optJSONObject("locale").toString().getBytes(EncodeConstants.ENCODING_UTF_8));
- }catch(Exception e){}
- writer.end();
-
- writer.end();
- }
-
- @Override
- public void readXML(XMLableReader reader) {
- String tagname = reader.getTagName();
- if("Locale".equals( tagname )){
- try{
- String value = new String(GeneralXMLTools.readByteArray(reader), EncodeConstants.ENCODING_UTF_8);
- JSONObject locale = new JSONObject(value);
- conf.put("locale", locale);
- }catch(Exception e){}
- }else if("item".equals( tagname )){
- String dt = reader.getAttrAsString("dt", "");
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
- String type = reader.getAttrAsString("type", "");
- try{
- if(!"h".equals(type)&&!"w".equals(type)){
- return ;
- }
- String year = getYear(format.parse(dt));
- JSONObject yJa = getCustom(year);
- yJa.optJSONArray(type).put(dt);
- }catch(Exception e){}
- }
- }
- }
复制代码 然后就是两个自定义函数了,一个判断是不是休息日,一个获取工作日或者休息日数量
- package com.midas.plugin.func;
- import java.util.Date;
- import com.fr.script.AbstractFunction;
- public class IsHoliday extends AbstractFunction {
- public static void main(String[]args){
- new com.fr.start.Designer(null);
- }
- private static final long serialVersionUID = 2940754222244608301L;
- @Override
- public Object run(Object[] params) {
- if(params.length == 1){
- return DateRecord.getInstance().isHoliday((Date) params[0]);
- }
- if(params.length == 2){
- return DateRecord.getInstance().isHoliday((Date) params[0],(Boolean)params[1]);
- }
- if(params.length == 3){
- return DateRecord.getInstance().isHoliday((Date) params[0],(Boolean)params[1],(Boolean)params[2]);
- }
- return null;
- }
- }
复制代码- package com.midas.plugin.func;
- import java.util.Date;
- import com.fr.script.AbstractFunction;
- @SuppressWarnings("serial")
- public class WHDateDif extends AbstractFunction {
-
- private int getDif(Date start,Date end){
- int days = (int) ((end.getTime() - start.getTime()) / (1000*3600*24));
- return days+1;
- }
-
- @Override
- public Object run(Object[] params) {
- Date start = WorkDay.format((Date)params[0]);
- Date end = WorkDay.format((Date)params[1]);
- if( 2==params.length ){
- return getDif( start, end) - DateRecord.getInstance().getHolidayCount(start, end);
- }
- String type = (String)params[2];
- if( "h".equals(type) ){
- return DateRecord.getInstance().getHolidayCount(start, end);
- }
- return getDif( start, end) - DateRecord.getInstance().getHolidayCount(start, end);
- }
- }
复制代码 下面是10-18年的缓存数和需要用到的JAR包
holiday.xml
(3.4 KB, 下载次数: 23)
jsoup-1.10.1.jar
(337.49 KB, 下载次数: 14)
核心类~获取每年的节假日安排情况的爬虫代码不提供,方法很简单,就是到国务院官网爬放假的公告,然后通过正则表达式解析出里面的节假日就可以了,有兴趣的可以自己研究研究~实在研究不出来的加我的报表群交流
编辑于 2018-4-11 18:26
|