万年历农历法定节假日数据查询工具

1.数据源

数据来源于百度搜索置顶日历

在这里插入图片描述

2.源码:

http调用及数据处理均采用了hutool, 也可以用别的工具。
hutool 依赖如下:

<dependency>
  	<groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>4.6.2</version>
</dependency>
package com.visy.utils;

import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * @author visy.wang
 * @description: 日历数据查询工具
 * @date 2023/1/29 15:55
 */
public class CalendarUtil {
    private static final String URL_V1 = "https://opendata.baidu.com/api.php";
    private static final String URL_V2 = "https://opendata.baidu.com/data/inner";
    private static final String JSONP_CALLBACK_NAME = "jsonp_callback";
    private static final Logger logger = LoggerFactory.getLogger(CalendarUtil.class);

    /**
     * 查询日历(V1)
     * 注意:返回结果的oDate采用的时区是0时区
     * @param year 年,如:2023
     * @param month 月,如:2
     * @param isJSONP 是否返回JSONP(默认返回JSON)
     * @return 返回当前月,上一个月以及下一个月的日历数据
     */
    public static JSONArray queryCalendarV1(int year, int month, boolean isJSONP){
        //拼接参数
        String url = URL_V1 + "?" + getQueryStrV1(year, month, isJSONP);
        return queryCalendar(url, isJSONP, json -> {
            //仅当状态=0时调用成功
            if(!"0".equals(json.getStr("status"))){
                logger.info("接口调用失败");
                return null;
            }
            //提取黄历数据
            return json.getByPath("data[0].almanac", JSONArray.class);
        });
    }

	/**
     * 查询日历(V2)
     * 注意:返回结果的oDate采用的时区是0时区
     * @param year 年,如:2023
     * @param month 月,如:2
     * @param isJSONP 是否返回JSONP(默认返回JSON)
     * @return 返回当前月,上一个月以及下一个月的日历数据
     */
    public static JSONArray queryCalendarV2(int year, int month, boolean isJSONP){
        //拼接参数
        String url = URL_V2 + "?" + getQueryStrV2(year, month, isJSONP);
        return queryCalendar(url, isJSONP, json -> {
            Integer resultCode = json.getInt("ResultCode");
            //仅当结果码=0时调用成功
            if(!Integer.valueOf(0).equals(resultCode)){
                logger.info("接口调用失败");
                return null;
            }
            //提取黄历数据
            return json.getByPath("Result[0].DisplayData.resultData.tplData.data.almanac", JSONArray.class);
        });
    }

    private static JSONArray queryCalendar(String url, boolean isJSONP, Function<JSONObject, JSONArray> parser){
        //拼接参数
        logger.info("完整请求地址: {}", url);
        //发起调用
        String response = HttpUtil.get(url);
        logger.info("原始响应结果: {}", response);
        //提取JSON
        String jsonBody;
        if(isJSONP){
            //返回结果为JSONP时,去除多余字符,提取JSON部分
            int start = response.indexOf("{"), end = response.lastIndexOf("}")+1;
            jsonBody = response.substring(start, end);
        }else{
            jsonBody = response;
        }
        logger.info("JSON响应体: {}", jsonBody);
        //解析返回结果
        return parser.apply(JSONUtil.parseObj(jsonBody));
    }

    private static String getQueryStrV1(int year, int month, boolean isJSONP){
        Map<String,Object> params = new HashMap<>();
        params.put("tn", "wisetpl");
        params.put("format", "json");
        params.put("resource_id", "39043");
        params.put("t", System.currentTimeMillis());
        params.put("query", year+"年"+month+"月");
        if(isJSONP){
            //不加这个参数返回结果为JSON,加了返回的是JSONP
            params.put("cb", JSONP_CALLBACK_NAME);
        }
        return toQueryStr(params);
    }

    private static String getQueryStrV2(int year, int month, boolean isJSONP){
        Map<String,Object> params = new HashMap<>();
        params.put("tn", "reserved_all_res_tn");
        params.put("type", "json");
        params.put("resource_id", "52109");
        params.put("apiType", "yearMonthData");
        params.put("query", year+"年"+month+"月");
        if(isJSONP){
            //不加这个参数返回结果为JSON,加了返回的是JSONP
            params.put("cb", JSONP_CALLBACK_NAME);
        }
        return toQueryStr(params);
    }

    private static String toQueryStr(Map<String,Object> params){
        List<String> kvList = new ArrayList<>();
        params.forEach((k, v) -> {
            kvList.add(k + "=" + v);
        });
        return URLUtil.encode(String.join("&", kvList), StandardCharsets.UTF_8);
    }
}
3.测试
package com.visy.utils;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;

/**
 * @author visy.wang
 * @date 2024/9/23 11:14
 */
public class CalendarUtilTest {
    public static void main(String[] args) {
        JSONArray list1 = CalendarUtil.queryCalendarV1(2023, 2, false);
        JSONArray list2 = CalendarUtil.queryCalendarV1(2023, 2, true);
        JSONArray list3 = CalendarUtil.queryCalendarV2(2023, 2, false);
        JSONArray list4 = CalendarUtil.queryCalendarV2(2023, 2, true);
        //只打印一行看看
        System.out.println(JSONUtil.formatJsonStr(list1.get(0).toString()));
        System.out.println("---------------------------------------------");
        System.out.println(JSONUtil.formatJsonStr(list2.get(0).toString()));
        System.out.println("---------------------------------------------");
        System.out.println(JSONUtil.formatJsonStr(list3.get(0).toString()));
        System.out.println("---------------------------------------------");
        System.out.println(JSONUtil.formatJsonStr(list4.get(0).toString()));
    }
}
4.输出
完整请求地址: https://opendata.baidu.com/api.php?t=1727062131671&query=2023%E5%B9%B42%E6%9C%88&format=json&resource_id=39043&tn=wisetpl
原始响应结果: {"status":"0","t":"1727062131671","set_cache_time":"","data":[]}
完整请求地址: https://opendata.baidu.com/api.php?t=1727062132396&query=2023%E5%B9%B42%E6%9C%88&format=json&resource_id=39043&tn=wisetpl&cb=jsonp_callback
原始响应结果: /**/jsonp_callback({"status":"0","t":"1727062132396","set_cache_time":"","data":[]})
完整请求地址: https://opendata.baidu.com/data/inner?query=2023%E5%B9%B42%E6%9C%88&resource_id=52109&tn=reserved_all_res_tn&type=json&apiType=yearMonthData
原始响应结果: {"DispExt":null,"QueryDispInfo":null,"ResultCode":0,"ResultNum":1,"QueryID":"3430800766","Result":[]}
完整请求地址: https://opendata.baidu.com/data/inner?query=2023%E5%B9%B42%E6%9C%88&resource_id=52109&tn=reserved_all_res_tn&type=json&apiType=yearMonthData&cb=jsonp_callback
原始响应结果: jsonp_callback({"DispExt":null,"QueryDispInfo":null,"ResultCode":0,"ResultNum":1,"QueryID":"3430807017","Result":[]})
{
    "animal": "虎",
    "avoid": "栽种.安门.治病.作灶",
    "cnDay": "日",
    "day": "1",
    "festivalList": "元旦",
    "gzDate": "己未",
    "gzMonth": "壬子",
    "gzYear": "壬寅",
    "isBigMonth": "1",
    "jiri": "0",
    "lDate": "初十",
    "lMonth": "腊",
    "lunarDate": "10",
    "lunarMonth": "12",
    "lunarYear": "2022",
    "month": "1",
    "oDate": "2022-12-31T16:00:00.000Z",
    "status": "1",
    "suit": "动土.祈福.安床.架马.开厕.祭祀.入殓.成人礼.成服.除服.伐木.结网.开池.求子",
    "term": "元旦",
    "timestamp": "1672502400",
    "type": "h",
    "year": "2023",
    "yjJumpUrl": "https://mobile.51wnl-cq.com/huangli_tab_h5/?posId=BDSS&STIME=2023-01-01",
    "yj_from": "51wnl"
}
---------------------------------------------
{
    "animal": "虎",
    "avoid": "栽种.安门.治病.作灶",
    "cnDay": "日",
    "day": "1",
    "festivalList": "元旦",
    "gzDate": "己未",
    "gzMonth": "壬子",
    "gzYear": "壬寅",
    "isBigMonth": "1",
    "jiri": "0",
    "lDate": "初十",
    "lMonth": "腊",
    "lunarDate": "10",
    "lunarMonth": "12",
    "lunarYear": "2022",
    "month": "1",
    "oDate": "2022-12-31T16:00:00.000Z",
    "status": "1",
    "suit": "动土.祈福.安床.架马.开厕.祭祀.入殓.成人礼.成服.除服.伐木.结网.开池.求子",
    "term": "元旦",
    "timestamp": "1672502400",
    "type": "h",
    "year": "2023",
    "yjJumpUrl": "https://mobile.51wnl-cq.com/huangli_tab_h5/?posId=BDSS&STIME=2023-01-01",
    "yj_from": "51wnl"
}
---------------------------------------------
{
    "animal": "虎",
    "avoid": "栽种.安门.治病.作灶",
    "cnDay": "日",
    "day": "1",
    "festivalInfoList":
    [
        {
            "baikeId": "137017",
            "baikeName": "元旦",
            "baikeUrl": "https://baike.baidu.com/item/元旦/137017",
            "name": "元旦"
        }
    ],
    "festivalList": "元旦",
    "gzDate": "己未",
    "gzMonth": "壬子",
    "gzYear": "壬寅",
    "isBigMonth": "1",
    "jiri": "0",
    "lDate": "初十",
    "lMonth": "腊",
    "lunarDate": "10",
    "lunarMonth": "12",
    "lunarYear": "2022",
    "month": "1",
    "oDate": "2022-12-31T16:00:00Z",
    "status": "1",
    "suit": "动土.祈福.安床.架马.开厕.祭祀.入殓.成人礼.成服.除服.伐木.结网.开池.求子",
    "term": "元旦",
    "timestamp": "1672502400",
    "type": "h",
    "year": "2023",
    "yjJumpUrl": "https://mobile.51wnl-cq.com/huangli_tab_h5/?posId=BDSS&STIME=2023-01-01",
    "yj_from": "51wnl"
}
---------------------------------------------
{
    "animal": "虎",
    "avoid": "栽种.安门.治病.作灶",
    "cnDay": "日",
    "day": "1",
    "festivalInfoList":
    [
        {
            "baikeId": "137017",
            "baikeName": "元旦",
            "baikeUrl": "https://baike.baidu.com/item/元旦/137017",
            "name": "元旦"
        }
    ],
    "festivalList": "元旦",
    "gzDate": "己未",
    "gzMonth": "壬子",
    "gzYear": "壬寅",
    "isBigMonth": "1",
    "jiri": "0",
    "lDate": "初十",
    "lMonth": "腊",
    "lunarDate": "10",
    "lunarMonth": "12",
    "lunarYear": "2022",
    "month": "1",
    "oDate": "2022-12-31T16:00:00Z",
    "status": "1",
    "suit": "动土.祈福.安床.架马.开厕.祭祀.入殓.成人礼.成服.除服.伐木.结网.开池.求子",
    "term": "元旦",
    "timestamp": "1672502400",
    "type": "h",
    "year": "2023",
    "yjJumpUrl": "https://mobile.51wnl-cq.com/huangli_tab_h5/?posId=BDSS&STIME=2023-01-01",
    "yj_from": "51wnl"
}
5.字段说明:
字段名描述示例值
oDate时间(0时区)2022-12-31T16:00:00.000Z
year年(阳历)2023
month月(阳历)1
day日(阳历)1
lunarYear年(农历)2022
lunarMonth月(农历)12
lunarDate日(农历)10
lMonth月(农历描述)
lDate日(农历描述)初十
gzYear年-干支壬寅
gzMonth月-干支壬子
gzDate日-干支己未
animal生肖年
cnDay星期描述(一二三四五六日)
isBigMonth是否是农历大月(1-是)1
term节假日描述(含节气)元旦
status节假日状态(1-休假,2-补班)1
type节假日类型h
yj_from数据来源51wnl
suit动土.祈福.安床.架马.开厕.祭祀.入殓.成人礼.成服.除服.伐木.结网.开池.求子
avoid栽种.安门.治病.作灶
6.版本说明

工具提供了两个版本,请求地址不一样,参数略微不同
两个版本都是百度搜索置顶日历,V1是早期的地址, V2是新地址
V1请求地址:https://opendata.baidu.com/api.php
V2请求地址:https://opendata.baidu.com/data/inner

7.其他方式查询法定节假日
	import cn.hutool.http.HttpUtil;
	import com.alibaba.fastjson.JSON;
	import com.alibaba.fastjson.JSONObject;
	
	import java.text.ParseException;
	import java.util.ArrayList;
	import java.util.Comparator;
	import java.util.List;
	import java.util.Map;

	public static void main(String[] args) throws ParseException {
        List<JSONObject> holidayList = getHolidayList(2025);
        System.out.println("节假日天数:"+holidayList.size());
        holidayList.forEach(System.out::println);
    }

    public static List<JSONObject> getHolidayList(int year){
        String url = String.format("https://timor.tech/api/holiday/year/%s", year);
        String respBody = HttpUtil.get(url);
        JSONObject result = JSON.parseObject(respBody);
        List<JSONObject> holidayList = new ArrayList<>();
        if(Integer.valueOf(0).equals(result.getInteger("code"))){
            JSONObject holiday = result.getJSONObject("holiday");
            for (Map.Entry<String, Object> entry : holiday.entrySet()) {
                JSONObject day = (JSONObject)entry.getValue();
                if(day.getBoolean("holiday")){
                	//法定节假日
                    JSONObject dayJson = new JSONObject();
                    dayJson.put("date", Integer.valueOf(day.getString("date").replace("-", "")));
                    dayJson.put("holiday",  day.getString("name"));
                    holidayList.add(dayJson);
                }else{
					//法定节假日补班
				}
            }
            holidayList.sort(Comparator.comparing(d -> d.getInteger("date")));
        }
        return holidayList;
    }
节假日天数:28
{"date":20250101,"holiday":"元旦"}
{"date":20250128,"holiday":"除夕"}
{"date":20250129,"holiday":"初一"}
{"date":20250130,"holiday":"初二"}
{"date":20250131,"holiday":"初三"}
{"date":20250201,"holiday":"初四"}
{"date":20250202,"holiday":"初五"}
{"date":20250203,"holiday":"初六"}
{"date":20250204,"holiday":"初七"}
{"date":20250404,"holiday":"清明节"}
{"date":20250405,"holiday":"清明节"}
{"date":20250406,"holiday":"清明节"}
{"date":20250501,"holiday":"劳动节"}
{"date":20250502,"holiday":"劳动节"}
{"date":20250503,"holiday":"劳动节"}
{"date":20250504,"holiday":"劳动节"}
{"date":20250505,"holiday":"劳动节"}
{"date":20250531,"holiday":"端午节"}
{"date":20250601,"holiday":"端午节"}
{"date":20250602,"holiday":"端午节"}
{"date":20251001,"holiday":"国庆节"}
{"date":20251002,"holiday":"国庆节"}
{"date":20251003,"holiday":"国庆节"}
{"date":20251004,"holiday":"国庆节"}
{"date":20251005,"holiday":"国庆节"}
{"date":20251006,"holiday":"中秋节"}
{"date":20251007,"holiday":"国庆节"}
{"date":20251008,"holiday":"国庆节"}
数据很详细 CREATE TABLE `zb_calendar` ( `GregorianDateTime` varchar(255) DEFAULT NULL COMMENT '公历日期时间', `LunarDateTime` varchar(255) DEFAULT NULL COMMENT '农历日期时间', `LunarShow` varchar(255) DEFAULT NULL, `IsJieJia` varchar(255) DEFAULT NULL, `LJie` varchar(255) DEFAULT NULL COMMENT '农历节日', `GJie` varchar(255) DEFAULT NULL COMMENT '公历节日', `Yi` varchar(255) DEFAULT NULL COMMENT '宜', `Ji` varchar(255) DEFAULT NULL COMMENT '忌', `ShenWei` varchar(255) DEFAULT NULL COMMENT '神位', `Taishen` varchar(255) DEFAULT NULL COMMENT '胎神', `Chong` varchar(255) DEFAULT NULL COMMENT '冲煞', `SuiSha` varchar(255) DEFAULT NULL COMMENT '岁煞', `WuxingJiazi` varchar(255) DEFAULT NULL COMMENT '五行甲子', `WuxingNaYear` varchar(255) DEFAULT NULL COMMENT '纳音五行年', `WuxingNaMonth` varchar(255) DEFAULT NULL COMMENT '纳音五行月', `WuxingNaDay` varchar(255) DEFAULT NULL COMMENT '纳音五行日', `MoonName` varchar(255) DEFAULT NULL COMMENT '农历月名称', `XingEast` varchar(255) DEFAULT NULL COMMENT '星宿吉凶(东方星座)', `XingWest` varchar(255) DEFAULT NULL COMMENT '四方(星座)', `PengZu` varchar(255) DEFAULT NULL COMMENT '彭祖百忌', `JianShen` varchar(255) DEFAULT NULL COMMENT '黄历12值神建', `TianGanDiZhiYear` varchar(255) DEFAULT NULL COMMENT '天干地支年', `TianGanDiZhiMonth` varchar(255) DEFAULT NULL COMMENT '天干地支月', `TianGanDiZhiDay` varchar(255) DEFAULT NULL COMMENT '天干地支日', `LMonthName` varchar(255) DEFAULT NULL COMMENT '农历月名称', `LYear` varchar(255) DEFAULT NULL COMMENT '生肖', `LMonth` varchar(255) DEFAULT NULL COMMENT '农历月', `LDay` varchar(255) DEFAULT NULL COMMENT '农历日', `SolarTermName` varchar(255) DEFAULT NULL COMMENT '农历节气的名称' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='万年历';
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值