不积跬步,无以至千里;不积小流,无以成江海。

Dean's blog

  • Join Us on Facebook!
  • Follow Us on Twitter!
  • LinkedIn
  • Subcribe to Our RSS Feed

基于度娘接口判断指定日期是否为工作日

在有些场景需要判断指定的日期是否为工作日,例如,在做数据运维时,有些任务必须是每工作日运行的,这就需要检查当前日期是否为工作日了。判断是否为工作日,不能简单的判断是否是周一至周五或是不是周末,还需要依据国家的法定假日安排。

法定假日中,有一些是以公历日期安排的,例如:元旦、劳动节、国庆节;有些是按农历日期安排,这个就在公历上没有一个固定的日期了,例如:清明节、端午节、中秋节、除夕、春节。另外,法定假期还可能涉及平时工作日调整的情况。

如果是自己去收集这些信息,就太麻烦了。幸好我们只要在度娘上直接搜索“日历”就会返回当前月份的月历,如果有法定假期或工作日调整的,都会有标注:

通过跟踪发现,她这个是依据一个网页接口返回的数据展示出来的。例如查询2020年1月的接口地址是:

https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=2020%E5%B9%B41%E6%9C%88&co=&resource_id=6018&t=1578357406127&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb=jQuery11020002977011609388569_1578357382912&_=1578357382916
有了接口就开干:
import requests
import json
import calendar, os, pathlib, datetime


def getYearHolidays(year):
    '''得到法定节假日安排'''

    if(datetime.datetime.now().year < year): return {}

    cachefile = os.path.join(os.getcwd(), 'caches', 'holidays'+ str(year) +'.json')
    if not pathlib.Path(cachefile).exists():
        pathlib.Path(os.path.dirname(cachefile)).parent.mkdir(parents=True, exist_ok=True)

        url = r'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query='+ str(year) + r'%E5%B9%B41%E6%9C%88&co=&resource_id=6018&t=1578357406127&ie=utf8&oe=gbk&format=json&tn=baidu&_=1578357382916'
        response = requests.get(url)
        res = json.loads(response.text)
        with(open(cachefile, 'wt', encoding='UTF-8')) as f:
            json.dump(res['data'][0]['holiday'], f, ensure_ascii=False)
        
        holidays = res['data'][0]['holiday']
    else:
        with(open(cachefile, encoding='UTF-8')) as f:
            holidays = json.load(f)


    days = {}
    for holiday in holidays:
        for x in holiday['list']:
            days[x['date']] = x['status'] #1为假日;2为工作日

    return days

def isWorkingDay(year, month, day):
    '''
    判断日期是否为工作日
        如果是由返回True,否则返回False
    '''
    #法定节检查
    holidays = getYearHolidays(year)
    dateStr = f"{year}-{month}-{day}"
    if(dateStr in holidays):
        return holidays[dateStr] != '1'

    #检查是否为普通的工作日(周一至五)或周末(周六、日)
    weekday = calendar.weekday(year, month, day)
    return weekday in [0, 1, 2, 3, 4]#0是周一
 测试结果:
print(isWorkingDay(2020, 1, 1))   #False
print(isWorkingDay(2020, 1, 2))   #True
但是使用这个也存在问题:
1、接口只返回近10年的节假日安排;
2、法定节假日安排要等国家节假日办颁布后才能查询,比如现在想查2021年的是没办法的
不允许评论
粤ICP备17049187号-1