前言:翻到了一位大神做的节假日api,https://blog.csdn.net/xinit1/article/details/72833988 作者:xinit1
获取指定日期的节假日信息
1、接口地址:http://api.goseek.cn/Tools/holiday?date=数字日期
2、返回数据:正常工作日对应结果为 0, 法定节假日对应结果为 1, 节假日调休补班对应的结果为 2,休息日对应结果为 3
3、节假日数据说明:本接口包含2017年起的中国法定节假日数据,数据来源国务院发布的公告,每年更新1次,确保数据最新
4、示例:
http://api.goseek.cn/Tools/holiday?date=20170528
返回数据:
{“code”:10000,“data”:1}
正好自己需要做简单的周末和节假日排班表,之前都是EXCEL下载人家做好的日历表,再手动找出哪些是节假日,最后再按照一定的规则分配加班人,现在可以用Python自动化完成了。
具体操作如下:
1、新建一个Excel文件,输入’2019/1/1’格式,然后下拉365天,接着用=TEXT(C2,“yyyymmdd”)来获得标准日期格式(如“20190101”)
2、调用API接口,获得每一天的返回数据
def get_holiday():
'''根据日期判断日期类型:正常工作日对应结果为 0, 法定节假日对应结果为 1, 节假日调休补班对应的结果为 2,休息日对应结果为 3'''
url = r'http://api.goseek.cn/Tools/holiday?date='
try:
for i in range(2, 367):
data = ws.Range('A' + str(i)).Value
new_url = url + data
r = requests.get(new_url)
time.sleep(1)
r.encoding = 'utf-8'
d = json.loads(r.text)
answer = d['data']
ws.Range('B' + str(i)).Value = answer
print('{}:{}'.format(data, answer))
except Exception as e:
print(e)
finally:
wb.Close(True)
xl.quit()
3、我定义的加班规则如下,优先级从大到小:
1)、2019年1月1号由A来做,手动输入了;
2)、如果每个月的1号是休息日,就由A来做;
3)、如果前天是休息日且由某人来做,那今天就不要让他做了,从剩下的人中选择加班天数较少的人来做;
4)、如果昨天是休息日且由某人来做,那今天就仍然由他做;
5)、以上三种情况都不满足的话,就选加班天数较少的人来做;
4、完整代码如下
import requests
import json
from win32com.client import Dispatch
from os import path
import time
def get_holiday():
'''根据日期判断日期类型:正常工作日对应结果为 0, 法定节假日对应结果为 1, 节假日调休补班对应的结果为 2,休息日对应结果为 3'''
url = r'http://api.goseek.cn/Tools/holiday?date='
try:
for i in range(2, 367):
data = ws.Range('A' + str(i)).Value
new_url = url + data
r = requests.get(new_url)
time.sleep(1)
r.encoding = 'utf-8'
d = json.loads(r.text)
answer = d['data']
ws.Range('B' + str(i)).Value = answer
print('{}:{}'.format(data, answer))
except Exception as e:
print(e)
finally:
wb.Close(True)
xl.quit()
def get_min(a, b, c):
'''获得a, b, c三者里的最小值'''
if (b<= a) and (b<= c):
return 'B'
elif (c<= a) and (c<= b):
return 'C'
else:
return 'A'
def get_abc(this_person, a, b, c):
'''根据获得的加班人姓名,进行赋值动作并输出新的a,b,c'''
ws.Range('E' + str(i)).Value = this_person
print('{}是休息日,由{}来加班'.format(date, this_person))
if this_person == 'A': a += 1
elif this_person == 'B': b += 1
elif this_person == 'C': c += 1
return a, b, c
xl = Dispatch("Excel.Application")
xl.Visible = False #True是显示, False是隐藏
xl.DisplayAlerts = 0
wb_path = path.abspath('.')+"\\" + r'2019年日历表.xlsx'
wb = xl.Workbooks.Open(wb_path)
ws = wb.Sheets('Sheet1')
a = 0 #代表加班人员A的目前加班天数,下同
b = 0
c = 0
person_dict = {'A': a, 'B': b, 'C': c}
for i in range(3, 367):
value = int(ws.Range('B' + str(i)).Value)
date = ws.Range('A' + str(i)).Value
day = int(date[-2:])
if (day == 1): if_first_day = 1 #判断是否为每个月的第一天
else: if_first_day = 0
if (value == 0) or (value == 2): #如果今天是工作日就pass
print('{}是工作日'.format(date))
continue
else:
if if_first_day == 1: #如果是每个月第一天或第二天就A来做
this_person = 'A'
ws.Range('E' + str(i)).Value = this_person
print('{}是休息日,由{}来加班'.format(date, this_person))
a += 1
elif int(ws.Range('B' + str(i-2)).Value) in (1, 3): #如果前天也是节假日或休息日,那今天不要让那个人加班了
qiantian_person = ws.Range('E' + str(i-2)).Value
person_list = ['A', 'B', 'C']
person_list.remove(qiantian_person)
if person_dict[person_list[0]] >= person_dict[person_list[1]]:
this_person = person_list[1]
else:
this_person = person_list[0]
a, b, c = get_abc(this_person, a, b, c)
elif int(ws.Range('B' + str(i-1)).Value) in (1, 3): #如果昨天也是节假日和休息日,就由昨天加班的人来做
pre_person = ws.Range('E' + str(i-1)).Value
this_person = pre_person
a, b, c = get_abc(this_person, a, b, c)
else:
this_person = get_min(a, b, c)
a, b, c = get_abc(this_person, a, b, c)
wb.Close(True)
xl.quit()