目录
依赖
<dependencies>
<!-- JSON工具类 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- JSON解析 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<!-- 实用工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
<!-- 开发简化 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
节假日数据返回结果类
HolidayResponse
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/** 节假日数据返回类
* @author Leslie Lee
* @version 2003/04/01
* @date 1956/09/12
*/
@Data
public class HolidayResponse {
@JsonProperty("code")
private int code; // 公共参数 - 状态码
@JsonProperty("msg")
private String msg; // 公共参数 - 错误信息
@JsonProperty("result")
private Result result; // 公共参数 - 返回结果集
/**
* 响应结果
*/
@Data
public static class Result {
@JsonProperty("update")
private boolean update; // 公共参数 - 是否更新法定节假日
@JsonProperty("list")
private List<HolidayItem> list; // 应用参数 - 节假日列表
}
/**
* 假期列表中的一个项目
*/
@Data
public static class HolidayItem {
@JsonProperty("holiday")
private String holiday; // 应用参数 - 节日日期
@JsonProperty("name")
private String name; // 应用参数 - 节假日名称(中文)
@JsonProperty("vacation")
private String vacation; // 应用参数 - 节假日数组
@JsonProperty("remark")
private String remark; // 应用参数 - 调休日数组
@JsonProperty("wage")
private String wage; // 应用参数 - 薪资法定倍数/按年查询时为具体日期
@JsonProperty("start")
private int start; // 应用参数 - 假期起点计数
@JsonProperty("now")
private int now; // 应用参数 - 假期当前计数
@JsonProperty("end")
private int end; // 应用参数 - 假期终点计数
@JsonProperty("tip")
private String tip; // 应用参数 - 放假提示
@JsonProperty("rest")
private String rest; // 应用参数 - 拼假建议
}
}
工具类
TianApiHolidayUtils
先创建好保存json文件的文件夹,例:D:\holiday
url:天行数据开放api
key:注册账号后生成的接口秘钥
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
/**
* 节假日工具类
*
* @author Leslie Lee
* @version 2003/04/01
* @date 1956/09/12
*/
@Slf4j
public class TianApiHolidayUtils<T> {
private static final String FILE_FORMAT = "D:/holiday/%s_holiday.json";
private static final String url = "https://apis.tianapi.com/jiejiari/index";
/**
* 获取日期中年份的节假日数据
*
* @param date 日期
* @return HolidayResponse
*/
public static HolidayResponse getHolidayConfig(LocalDateTime date) {
// 节假日文件路径
String savePath = String.format(FILE_FORMAT, DateUtil.format(date, "yyyy"));
// 从文件中读取节假日数据
HolidayResponse response = readJsonFromFile(savePath);
if (response == null) {
Map<String, Object> params = new HashMap<>();
params.put("key", "接口秘钥");// key
params.put("date", date);
params.put("type", 1);// 类型 0:批量 1:按年 2:按月 3:范围
// params.put("mode", 1);// 1:同时返回中外特殊节日信息
response = getHolidayFromApi(url, params);
writeJsonToFile(response, savePath);
}
return response;
}
/**
* 从文件中读取json数据
*
* @param filePath 文件路径
* @return HolidayResponse
*/
public static HolidayResponse readJsonFromFile(String filePath) {
if (Files.exists(Paths.get(filePath))) {// 存在就直接从文件中获取
try (FileInputStream fis = new FileInputStream(filePath)) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(fis, HolidayResponse.class);
} catch (Exception e) {
log.error("节假日文件读取失败 : {} , {}", filePath, e.getMessage());
}
}
return null;
}
/**
* 将json数据写入json文件
*
* @param jsonObject HolidayResponse
* @param filePath 文件路径
*/
public static void writeJsonToFile(HolidayResponse jsonObject, String filePath) {
if (jsonObject != null) {
try (FileOutputStream fos = new FileOutputStream(filePath)) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(fos, jsonObject);
log.info("节假日文件写入成功 : {} , {}", filePath, jsonObject);
} catch (Exception e) {
log.error("节假日文件写入失败 : {} , {}", filePath, e.getMessage());
}
} else
log.error("写入节假日文件失败,数据为空,预保存路径为:{}", filePath);
}
/**
* 提取返回数据里的节假日和调休列表
*
* @param response 返回数据
* @param vacationList 节假日列表
* @param workDayList 补班列表
*/
public static void extracted(HolidayResponse response, Map<LocalDate, LocalDate> vacationList, Map<LocalDate, LocalDate> workDayList) {
// 节假日列表及补班的周末
response.getResult().getList().forEach(item -> {
if (StringUtils.isNotEmpty(item.getWage())) {
String[] vList = item.getVacation().split("\\|");
for (String wage : vList) {
// 不需要上班的工作日
LocalDate parse = LocalDate.parse(wage, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
vacationList.put(parse, parse);
}
}
if (StringUtils.isNotEmpty(item.getRemark())) {
String[] workList = item.getRemark().split("\\|");
for (String work : workList) {
// 需要上班的周末
LocalDate parse = LocalDate.parse(work, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
workDayList.put(parse, parse);
}
}
});
}
/**
* 从api获取节假日数据
*
* @param url api路径
* @param params 参数
* @return HolidayResponse
*/
public static HolidayResponse getHolidayFromApi(String url, Map<String, Object> params) {
String rspBody = HttpUtil.post(url, params);
// 将json转换为对象
Gson gson = new Gson();
return gson.fromJson(rspBody, HolidayResponse.class);
}
/**
* 计算两个日期之间的工作天数
* @param startDate 开始日期
* @param endDate 结束日期
* @return 工作天数
*/
public static int calculateWorkingDays(LocalDate startDate, LocalDate endDate) {
if (startDate == null || endDate == null) {
return 0;
}
int workingDays = 0;// 返回工作天数
int startDateYear = startDate.getYear();
int endDateYear = endDate.getYear();
if (startDateYear == endDateYear) {
HolidayResponse response = getHolidayConfig(startDate.atStartOfDay());
// 节假日,只算周一到周五的
Map<LocalDate, LocalDate> vacationList = new HashMap<>();
// 补班列表,表示周末补班的
Map<LocalDate, LocalDate> workDayList = new HashMap<>();
extracted(response, vacationList, workDayList);
LocalDate current = startDate;
while (!current.isAfter(endDate)) {
// 排除节假日
if (!vacationList.containsKey(current) && current.getDayOfWeek() != DayOfWeek.SATURDAY && current.getDayOfWeek() != DayOfWeek.SUNDAY) {
workingDays++;
}
current = current.plusDays(1);
}
} else {
LocalDate currentYear = startDate;
LocalDate current = startDate;
Map<LocalDate, LocalDate> vacationListAll = new HashMap<>();
Map<LocalDate, LocalDate> workDayListAll = new HashMap<>();
while (startDateYear < endDateYear) {
HolidayResponse response = getHolidayConfig(currentYear.atStartOfDay());
// 节假日,只算周一到周五的
Map<LocalDate, LocalDate> vacationList = new HashMap<>();
// 补班列表,表示周末补班的
Map<LocalDate, LocalDate> workDayList = new HashMap<>();
extracted(response, vacationList, workDayList);
vacationList.putAll(vacationListAll);
workDayList.putAll(workDayListAll);
currentYear.plusYears(1);
startDateYear++;
}
while (!current.isAfter(endDate)) {
// 排除节假日
if (!vacationListAll.containsKey(current) && current.getDayOfWeek() != DayOfWeek.SATURDAY && current.getDayOfWeek() != DayOfWeek.SUNDAY) {
workingDays++;
}
current = current.plusDays(1);
}
}
return workingDays;
}
}
Leslie Lee 随笔