【日历】生成ics日历信息
参考
https://zhuanlan.zhihu.com/p/547193192
https://blog.csdn.net/Snakewood/article/details/130204963
解析步骤
目前有2种思路
解析百度接口
通过调用 https://sp1.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php
接口,拉取日历信息后再生成ics日历信息
def baiduContent(year): festival_lst = [] # 因该接口传入的时间,查询了前一个月,当前月和后一个月的数据,所以只需要2、5、8、11即可全部获取到。比如查询5月份,则会查询4,5,6月分的数据 months = ["2", "5", "8", "11"] for month in months: ts = int(time.time() * 1000) domain = "https://sp1.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&format=json&resource_id=39043&query=" url = domain + str(year) + "年" + month + "月&t=" + str(ts) response = requests.get(url) content = response.text root = json.loads(content) almanac = root["data"][0]["almanac"] for item in almanac: if ('status' in item and item["status"] == '1'): current_date = convert_to_date(item["year"] + "年" + item["month"] + "月" + item["day"] + "日", year) festival = '' if ('term' in item): festival = item["term"] fest = FestivalModel(current_date, festival, '', 1) festival_lst.append(fest) elif ('status' in item and item["status"] == '2'): current_date = convert_to_date(item["year"] + "年" + item["month"] + "月" + item["day"] + "日", year) festival = '' if ('term' in item): festival = item["term"] fest = FestivalModel(current_date, festival, '', 2) festival_lst.append(fest)
解析法定节假日通知
通过访问 https://www.gov.cn/zhengce/content/202310/content_6911527.htm 页面,解析通知内容后再生成ics日历信息
def getfestival(year, content): festival_lst = [] for item in content.split('\n'): if not item: item = '' item = item.strip() if item == "": continue if "放假," in item: idx1 = item.find('、') idx2 = item.find(':') idx3 = item.find('放假,') festival = item[idx1 + 1: idx2] date = item[idx2 + 1: idx3] if "、" in festival: festival_many = festival.split('、') festival = festival_many[1] appointed_date = convert_to_date(date, year) fest = FestivalModel(appointed_date, festival, '', 1) festival_lst.append(fest) # 处理与周末连休 if "与周末连休" in item: weekday = appointed_date.weekday() if weekday == 0: festival_sun = FestivalModel(appointed_date - timedelta(days=1), festival, '', 1) festival_lst.append(festival_sun) festival_sat = FestivalModel(appointed_date - timedelta(days=2), festival, '', 1) festival_lst.append(festival_sat) elif weekday == 4: festival_sat = FestivalModel(appointed_date + timedelta(days=1), festival, '', 1) festival_lst.append(festival_sat) festival_sun = FestivalModel(appointed_date + timedelta(days=2), festival, '', 1) festival_lst.append(festival_sun) elif "放假调休," in item: idx1 = item.find('、') idx2 = item.find(':') idx3 = item.find('放假调休,') festival = item[idx1 + 1: idx2] date_range = item[idx2 + 1: idx3] if "、" in festival: festival_many = festival.split('、') festival = festival_many[1] # 处理10月1日至7日这样的日期 date_continuous = date_range.split('至') start = date_continuous[0] end = date_continuous[1] if "月" not in end: end = start[0:start.find('月') + 1] + end start_date = convert_to_date(start, year) end_date = convert_to_date(end, year) current_date = start_date while current_date <= end_date: fest = FestivalModel(current_date, festival, '', 1) festival_lst.append(fest) current_date += timedelta(days=1) # 处理补班 many_sentence = item.split('。') for single_sentence in many_sentence: if "上班" in single_sentence: many_work = single_sentence.split('、') for single_work in many_work: left_bracket = single_work.find('(') date_work = single_work[0:left_bracket] fest = FestivalModel(convert_to_date(date_work, year), festival, '', 2) festival_lst.append(fest)
生成步骤
通过上面的解析,得到节假日信息的数组,再遍历输出ics的内容
def getics(festival_lst, year): print("BEGIN:VCALENDAR") print("VERSION:2.0") print("X-WR-CALNAME:" + str(year) + "订阅法定节假日") print("X-APPLE-CALENDAR-COLOR:#FBD36A") print("X-WR-TIMEZONE:Asia/Shanghai") festival_lst = sorted(festival_lst, key=lambda x: x.dt) idx = 1 for item in festival_lst: formatted_date = item.dt.strftime("%Y%m%d") print("BEGIN:VEVENT") print("UID:" + str(year) + "-" + f"{idx:04d}") print("DTSTART;VALUE=DATE:" + formatted_date) print("DTEND;VALUE=DATE:" + formatted_date) print("SUMMARY:" + item.festivalTips) print("SEQUENCE:0") print("BEGIN:VALARM") print("TRIGGER;VALUE=DATE-TIME:19760401T005545Z") print("ACTION:NONE") print("END:VALARM") print("END:VEVENT") idx += 1 print("END:VCALENDAR")
效果预览
将生成的内容保存到ics上传服务器,即可供客户端使用。比如ios手机订阅日历
BEGIN:VCALENDAR VERSION:2.0 X-WR-CALNAME:2024订阅法定节假日 X-APPLE-CALENDAR-COLOR:#FBD36A X-WR-TIMEZONE:Asia/Shanghai BEGIN:VEVENT UID:2024-0001 DTSTART;VALUE=DATE:20240101 DTEND;VALUE=DATE:20240101 SUMMARY:元旦(休息) SEQUENCE:0 BEGIN:VALARM TRIGGER;VALUE=DATE-TIME:19760401T005545Z ACTION:NONE END:VALARM END:VEVENT END:VCALENDAR