(目录)

现有方案:chinesecalendar

使用chinesecalendar库可以实现:判断一天是不是法定节假日/法定工作日(查看节假日安排)

  • https://pypi.org/project/chinesecalendar/
  • https://github.com/LKI/chinese-calendar/

安装

pip install chinesecalendar

使用示例

import datetime

# 判断 2018年4月30号 是不是节假日
from chinese_calendar import is_holiday, is_workday

april_last = datetime.date(2018, 4, 30)
assert is_workday(april_last) is False

缺点:

  • 1、更新不及时,或需要手动更新才能判断,由于次年的节假日安排,取决于国务院发布的日程。 所以本项目一般会在国务院更新以后,发布新的版本。 按照以往的经验,一般是每年的 11月 前后发布新版本。
  • 2、支持的版本有点高,Python :: 3.8起步,不支持低版本

基于网络的方案

可以使用现有的维护的比较好的网站数据,比如:https://wannianrili.bmcx.com/,通过网页请求解析获取日历数据,这样就能获取到实时的数据,缺点也很明显,需要网络请求,如果考虑性能的场景下,可能不适用。

依赖两个第三方库:

pip install requests parsel

代码文件,可以放到项目的utils工具包内

# -*- coding: utf-8 -*-
"""
@File    : calendar_util.py
@Date    : 2024-04-03
"""
import json
import re

import requests
from parsel import Selector


def get_calendar(year_and_month):
    """
    数据来源:https://wannianrili.bmcx.com/

    @return:

    {
      "2024-04-01": {
        "class_name": "",
        "comment": "愚人节"
        }
    }
    """

    # https://wannianrili.bmcx.com/ajax/?q=2024-04&v=22121303
    url = 'https://wannianrili.bmcx.com/ajax/'

    params = {
        'q': year_and_month,
        'v': '22121303'
    }

    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0"
    }

    res = requests.get(url, params=params, headers=headers)
    
    sel = Selector(text=res.text)
    rows = sel.css('.wnrl_riqi')

    data = {}
    for row in rows:
        class_name = row.css('a::attr(class)').extract_first('').strip()
        day = row.css('a::attr(onclick)').extract_first('').strip()
        comment = row.css('.wnrl_td_bzl::text').extract_first('').strip()

        ret = re.search('\d{4}-\d{2}-\d{2}', day)
        day = ret.group(0)

        data[day] = {
            'class_name': class_name,
            'comment': comment
        }

    return data


def get_day_item(day):
    """

    @param day:
    @return:
    {
        "class_name": "",
        "comment": "愚人节"
    }
    """
    # 2024-05-04 => 2024-05
    calendar = get_calendar('-'.join(day.split('-')[:2]))
    # print(json.dumps(calendar, indent=2, ensure_ascii=False))
    return calendar.get(day)


def is_workday(day):
    # 工作日
    workday_class_list = ['', 'wnrl_riqi_ban']

    day_item = get_day_item(day)

    if day_item:
        if day_item.get('class_name') in workday_class_list:
            return True
        else:
            return False


def is_holiday(day):
    # 节假日
    holiday_class_list = ['wnrl_riqi_xiu', 'wnrl_riqi_mo']
    day_item = get_day_item(day)

    if day_item:
        if day_item.get('class_name') in holiday_class_list:
            return True
        else:
            return False


if __name__ == '__main__':
    print(is_holiday('2024-05-04')) # True

使用china-calendar

基于以上代码,作者封装了一个库,可以直接使用

文档:

  • https://github.com/mouday/china-calendar
  • https://pypi.org/project/china-calendar/

安装

pip install china-calendar

使用示例:

import china_calendar

# 清明节
assert china_calendar.is_holiday('2024-04-04') == True

assert china_calendar.is_workday('2024-04-04') == False