在做项目时遇到一个需求,需要计算两个时间点之间的工作日。便于统计项目时间统计。
其中有两个方向:
第一,调用开源的api,“http://api.goseek.cn/Tools/holiday?date={时间}”,这个api会返回:工作日:0;节假日:1;工作日:2),然后根据返回的数据进行判断,当然这个会受到网络和别人api的限制,但是好处是我们不用去维护节假日,因为这个是国务院每年发布,我们自己要维护的话很繁琐。
第二,将本年的节假日存在数据库中,然后对两个日期之间进行逻辑操作,当然这个就很繁琐,维护成本大一点,本来就是一个小东西,这个直接从数据库拿对于效率来说就要高一点了。
我选择的是第一种,方便嘛。然后对其中的方法进行重构,看起来爽一点,下面是代码,当然是第一版,有bug请联系我,后面测试我也会补充。
package com.xiaowei.worksystem.utils;
import com.alibaba.fastjson.JSONObject;
import sun.net.www.protocol.http.HttpURLConnection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class WorkdayCalculationUtils {
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
/*
* 传入查询工作日api地址,用于查询当天是否是工作日,返回的是JSON格式的数据,需要在代码中进行转换。
* */
public static String getData(String addess){
URL url = null;
HttpURLConnection httpConn = null;
BufferedReader in = null;
StringBuffer sb = new StringBuffer();
try{
url = new URL(addess);
in = new BufferedReader(new InputStreamReader(url.openStream(),"utf-8") );
String str = null;
while((str = in.readLine()) != null) {
sb.append( str );
}
} catch (Exception ex) {
ex.printStackTrace();
} finally{
try{
if(in!=null) {
in.close();
}
}catch(IOException ex) {
ex.printStackTrace();
}
}
String data =sb.toString();
return data;
}
/**
* 两个日期相减
* @param beginDateStr
* @param endDateStr
* @return
*/
public static long getDaySub(String beginDateStr,String endDateStr){
long day=0;
SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
Date beginDate;
Date endDate;
try{
beginDate = format.parse(beginDateStr);
endDate= format.parse(endDateStr);
day=(endDate.getTime()-beginDate.getTime())/(24*60*60*1000);
//System.out.println("相隔的天数="+day);
} catch (ParseException e){
// TODO 自动生成 catch 块
e.printStackTrace();
}
return day+1;
}
/*
* 计算两个时间点的工作日
*
* */
public static long getWorkDayBetweenStartAndEnd(String startTime,String endTime) throws ParseException {
//工作日
long workDay=0;
//先算出两个时间中间的天数
long dayOfMiddle=getDaySub(startTime,endTime);
//从开始时间起,算出中间的周末和及假日
for(int i=0;i<dayOfMiddle;i++){
Date now=sdf.parse(startTime);
Calendar c = Calendar.getInstance();
c.setTime(now);
c.set(Calendar.DATE, c.get(Calendar.DATE) + i);
String urlData= sdf.format(c.getTime());
String urlDress= "http://api.goseek.cn/Tools/holiday?date="+urlData;
//获得当前是否是工作日
String data=getData(urlDress);
JSONObject json = getjson(data);
String value=json.get("data").toString();
if(value.equals("0")){
workDay++;
}
}
return workDay;
}
//json串转化为json对象
public static JSONObject getjson(String data) {
JSONObject json = JSONObject.parseObject(data);
return json;
}
}