如何用Python做日历?

如何用Python做日历?_第1张图片

在后台回复【阅读书籍】

即可获取python相关电子书~

Hi,我是山月。

2022年已经过去一周了,现在山月已经习惯把年份写成2022啦。也正是这个习惯,把我从2021年已经过去了的恍惚感中拉了出来。

希望新的一年,我们都能变的更优秀一点~b6a08507706c5231606282590ef96288.png6ded77aedea017121d6d8c8196d8bfc5.png1a8f97bf9970630b7c4b1e5a64a03359.png

好啦,下面就跟着山月一起用Python做份日历吧。

现在,先想想你一般用的日历是什么样子的?有哪些元素?

这是山月根据日常用的日历制作的2022年1月的日历:

如何用Python做日历?_第2张图片

想得到完整代码的在后台回复【2022年日历】即可哦~

01

准备工作

1、用到的几个库:datetime, calendar, xlwt,borax。

其中xlwt和borax需要安装,直接用pip进行安装就可以了。

2、2022年放假安排

查看地址:http://www.gov.cn/zhengce/content/2021-10/25/content_5644835.htm

如何用Python做日历?_第3张图片

根据放假安排,我们可以做出三个字典:festival_dict(节日信息),holidays_dict(节假日信息),switch_dict(调班信息)。

#2022年节日
festival_dict = {

    datetime.date(year=2022, month=1, day=1) : "元旦",
    datetime.date(year=2022, month=1, day=31) :  "除夕",
    datetime.date(year=2022, month=2, day=1) : "春节",
    datetime.date(year=2022, month=4, day=5) : "清明节",
    datetime.date(year=2022, month=5, day=1) : "劳动节",
    datetime.date(year=2022, month=6, day=3) : "端午节",
    datetime.date(year=2022, month=9, day=10) : "中秋节",
    datetime.date(year=2022, month=10, day=1) : "国庆节",

}

#2022年节假日
holidays_dict = {

    datetime.date(year=2022, month=1, day=1) : '元旦' , 
    datetime.date(year=2022, month=1, day=2) : '元旦' , 
    datetime.date(year=2022, month=1, day=3) : '元旦' ,
    datetime.date(year=2022, month=1, day=31): '春节',
    datetime.date(year=2022, month=2, day=1): '春节',
    datetime.date(year=2022, month=2, day=2): '春节',
    datetime.date(year=2022, month=2, day=3): '春节',
    datetime.date(year=2022, month=2, day=4): '春节',
    datetime.date(year=2022, month=2, day=5): '春节',
    datetime.date(year=2022, month=2, day=6): '春节',
    datetime.date(year=2022, month=4, day=3): '清明节',
    datetime.date(year=2022, month=4, day=4): '清明节',
    datetime.date(year=2022, month=4, day=5): '清明节',
    datetime.date(year=2022, month=4, day=30): '劳动节',
    datetime.date(year=2022, month=5, day=1): '劳动节',
    datetime.date(year=2022, month=5, day=2): '劳动节',
    datetime.date(year=2022, month=5, day=3): '劳动节',
    datetime.date(year=2022, month=5, day=4): '劳动节',
    datetime.date(year=2022, month=6, day=3): '端午节',
    datetime.date(year=2022, month=6, day=4): '端午节',
    datetime.date(year=2022, month=6, day=5): '端午节',
    datetime.date(year=2022, month=9, day=10) : '中秋节',
    datetime.date(year=2022, month=9, day=11) : '中秋节',
    datetime.date(year=2022, month=9, day=12) : '中秋节',
    datetime.date(year=2022, month=10, day=1): '国庆节',
    datetime.date(year=2022, month=10, day=2): '国庆节',
    datetime.date(year=2022, month=10, day=3): '国庆节',
    datetime.date(year=2022, month=10, day=4): '国庆节',
    datetime.date(year=2022, month=10, day=5): '国庆节',
    datetime.date(year=2022, month=10, day=6): '国庆节',
    datetime.date(year=2022, month=10, day=7): '国庆节',
}

# 2022年调班
switch_dict = {

    datetime.date(year=2022, month=1, day=29): '春节',
    datetime.date(year=2022, month=1, day=30): '春节',
    datetime.date(year=2022, month=4, day=2): '清明节',
    datetime.date(year=2022, month=4, day=24): '劳动节',
    datetime.date(year=2022, month=5, day=7): '劳动节',
    datetime.date(year=2022, month=10, day=8): '国庆节' ,
    datetime.date(year=2022, month=10, day=9): '国庆节' ,
}

# 获取三个字典中的所有键
all_festival_days = list(festival_dict.keys())
all_holidays_days = list(holidays_dict.keys())
all_switch_days = list(switch_dict.keys())

02

实现目标

1、得到2022年1月的日历

import calendar

# 2022年1月
calendar_year = 2022
calendar_month = 1

# 得出2022年1月的日历
calendar.setfirstweekday(firstweekday=0) #将星期一设置为一周第一天
list_date = calendar.monthcalendar(calendar_year, calendar_month)
print(list_date)

运行结果:

[[0, 0, 0, 0, 0, 1, 2], [3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 30], [31, 0, 0, 0, 0, 0, 0]]

可以看出,monthcalendar(year, month)返回的是按周划分的一个月中天数的列表,不是当前月份的天数为0。

其中返回的列表里是由6个列表组成的,这6个列表是由7个元素组成的,代表了周一到周末的7天。

2、得出日期对应的农历

from borax.calendars import LunarDate

# 2022年1月2日
calendar_year = 2022
calendar_month = 1
date = 2

#得出2022年1月2日的农历日期,格式只显示日期
lunar_date = LunarDate.from_solar_date(calendar_year, calendar_month, date)
lunar_day = lunar_date.strftime('%D') 
print(lunar_day)

运行结果:

三十

我们翻看日历,可以发现2022年1月2日的农历是十一月三十。

那如果这个日期是节日,我们不想显示农历日期,而改用节日怎么办呢?

把我们准备的字典festival_dict(节日信息)用起来吧。

比如2022年1月31日是除夕:

import datetime

# 2022年1月31日
calendar_year = 2022
calendar_month = 1
date = 31
date_day = datetime.date(year=calendar_year, month=calendar_month, day=date)

festival_dict = {

    datetime.date(year=2022, month=1, day=1) : "元旦",
    ...
    
    '''为了更直观,这里把字典的内容省去了,详情可以看上面'''

}

all_festival_days = list(festival_dict.keys())

if date_day in all_festival_days:
    print(festival_dict[date_day])

运行结果:

除夕

这个时候就得到了节日啦。

3、节假日放假休息与调班

继续运用准备好的字典holidays_dict(节假日信息),switch_dict(调班信息)。

1)节假日休息

比如我们知道2022.1.3是元旦的最后一天,这一天应该要显示个【休】~5d88fe88218089e5147ee4a89e684000.pnga7f5a09b50d3272ae5329f5c1a18ea9f.png62f9455dc734b8f0d452e80713ad1c84.png

import datetime

# 2022年1月3日
calendar_year = 2022
calendar_month = 1
date = 3
date_day = datetime.date(year=calendar_year, month=calendar_month, day=date)

holidays_dict = {

    datetime.date(year=2022, month=1, day=1) : '元旦' , 
    ...
    
    '''为了更直观,这里把字典的内容省去了,详情可以看上面'''
}

all_holidays_days = list(holidays_dict.keys())

if date_day in all_holidays_days:
    print('休')
else:
    print('休息啥,搬砖去')

运行结果:

让人非常高兴的一个字~

2)节假日调班

对于单休的人来说,最怕调班周末,这意味着要连续上两个星期的班。0c30b04131a9ea58a1caffca0077426e.png7b608d17dc0beeb7cd05ba635d9ee619.png7481431434519ea7014376a9bb3da255.png

2022年1月的29和30需要为春节调班。以29号为例,我们来看看怎么实现吧。

import datetime

# 2022年1月29日
calendar_year = 2022
calendar_month = 1
date = 29
date_day = datetime.date(year=calendar_year, month=calendar_month, day=date)

switch_dict = {

    datetime.date(year=2022, month=1, day=29): '春节',
    ...
    
    '''为了更直观,这里把字典的内容省去了,详情可以看上面'''
}

all_switch_days = list(switch_dict.keys())

if date_day in all_switch_days:
    print('班')
else:
    print('休息啥,搬砖去')

运行结果:

bingo~

当然,在制作日历的过程里,我们要判断:如果是休息,则写个【休】;如果是调班,则写个【班】;否则就空白。

其实这样也很简单,用if...elif...else来判断就行啦。同学们可以自己想想,也可以看山月提供的完整代码。

4、日历显示

这里山月选择用excel把它呈现出来。用到的库是xlwt,关于xlwt的基础知识,山月之前已经分享过了,忘记了的同学请看

Python自动化办公:xlwt万字教程

Python自动化办公:xlwt教程(二)

对于我们的日历设计

  • 第2行显示日历的年月

  • 第3行显示星期一到星期日

  • 每个日期由2行2列组成,比如D4:E5组成了日期1号。其中D4显示日期;E4显示【休】or【班】or空白;D5:E5是个合并单元格,显示对应的农历日期/节日。

  • 为了美观,进行一些格式设置

03

完成日历

下面就是整合啦~

同样为了直观,山月把三个字典的内容省略了,自己实际运行的时候记得在上面复制噢,或者选择在后台回复【2022年日历】找山月要

import datetime, calendar, xlwt
from borax.calendars import LunarDate

#2022年节日
festival_dict = {

    datetime.date(year=2022, month=1, day=1) : "元旦",
    '''为了更直观,这里把字典的内容省去了,详情可以看上面'''

}

#2022年节假日
holidays_dict = {

    datetime.date(year=2022, month=1, day=1) : '元旦' , 
    '''为了更直观,这里把字典的内容省去了,详情可以看上面'''
}

# 2022年调班
switch_dict = {

    datetime.date(year=2022, month=1, day=29): '春节',
    '''为了更直观,这里把字典的内容省去了,详情可以看上面'''
}

# 获取三个字典中的所有键
all_festival_days = list(festival_dict.keys())
all_holidays_days = list(holidays_dict.keys())
all_switch_days = list(switch_dict.keys())

# 2022年*月
calendar_year = 2022
calendar_month = 1

# 得出2022年*月的日历
calendar.setfirstweekday(firstweekday=0)  #将星期一设置为一周第一天
list_date = calendar.monthcalendar(calendar_year, calendar_month)


# 创建一个新的工作薄及工作表
wb = xlwt.Workbook(encoding='utf-8',style_compression=0)  
ws = wb.add_sheet('日历',cell_overwrite_ok=True) 
ws.set_show_grid(0)     #工作表隐藏网格线

#设置写入格式
style_month = xlwt.easyxf('font: bold True, height 320 ; alignment: horz center, vert center; borders: left thin, right thin, top thin, bottom thin ')
style_week = xlwt.easyxf('font: bold True ; alignment: horz center, vert center; borders: left thin, right thin, top thin, bottom thin ')
style_date = xlwt.easyxf('font: height 280  ; alignment: horz right, vert center; borders: left thin , top thin')
style_lunar_date = xlwt.easyxf('font: height 160  ; alignment: horz center, vert top; borders: left thin, right thin, bottom thin  ')
style_holiday = xlwt.easyxf('font: height 160, colour_index red ; alignment: horz left, vert center ; borders: right thin ')


# 设置行高
style_550 = xlwt.easyxf('font:height 550;')  
style_400 = xlwt.easyxf('font:height 400;') 
style_350 = xlwt.easyxf('font:height 350;') 
row_2 = ws.row(1)
row_3 = ws.row(2)
row_2.set_style(style_550)
row_3.set_style(style_400)
for row_num in [3,5,7,9,11,13]:
    row_height = ws.row(row_num)
    row_height.set_style(style_350)


#写抬头说明是2022年某月
calendar_text = '2022年' + str(calendar_month) + '月'
ws.write_merge(1, 1, 1, 14, calendar_text, style_month)  

#写抬头显示星期几
week_list = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
row_start = -1
row_end = 0
for i in range(7):
    row_start += 2 
    row_end += 2
    ws.write_merge(2, 2, row_start, row_end, week_list[i], style_week)

#绘写日历
row_date_list = [3, 5, 7, 9, 11, 13]
col_date_list = [1, 3, 5 , 7 , 9, 11, 13]
for row, week_list in enumerate(list_date):
    for col, date in enumerate(week_list):
        if date != 0:

            #写日期
            ws.write(row_date_list[row], col_date_list[col], date, style_date) 

            date_day = datetime.date(year=calendar_year, month=calendar_month, day=date)

            #写农历,如果是节日写节日
            if date_day in all_festival_days:
                ws.write_merge(row_date_list[row]+1, row_date_list[row]+1, col_date_list[col], col_date_list[col]+1, festival_dict[date_day], style_lunar_date) 
            else:
                # 将公历日期转化为农历日期
                lunar_date = LunarDate.from_solar_date(calendar_year, calendar_month, date)
                lunar_day = lunar_date.strftime('%D') 
                ws.write_merge(row_date_list[row]+1, row_date_list[row]+1, col_date_list[col], col_date_list[col]+1, lunar_day, style_lunar_date) 
            
            #写节假日休息
            if date_day in all_holidays_days:
                ws.write(row_date_list[row], col_date_list[col]+1, '休', style_holiday)
            #写节假日调班
            elif date_day in all_switch_days:
                ws.write(row_date_list[row], col_date_list[col]+1, '班', style_holiday)
            else:
                ws.write(row_date_list[row], col_date_list[col]+1, ' ', style_holiday)
       
        else:
            ws.write(row_date_list[row], col_date_list[col], ' ', style_date)
            ws.write_merge(row_date_list[row]+1, row_date_list[row]+1, col_date_list[col], col_date_list[col]+1, ' ', style_lunar_date) 
            ws.write(row_date_list[row], col_date_list[col]+1, ' ', style_holiday)


wb.save('2022年1月日历.xls')  #保存excel

完成~

当然,这是2022年某个月的日历代码,如果是要一整年的,可以用循环~这个就交给大家去尝试啦。

最后,也许有小伙伴会说每年还要做字典?这样不效率啊。

其实我们有一个节假日的库:chinesecalendar。

官网:https://pypi.org/project/chinesecalendar/

github:https://github.com/LKI/chinese-calendar

它目前最新版本已经更新到了2022年。

其实它的内核也是把一个个节假日日期整理成一个"wheel车轮",这样下次可以就直接使用了。

如何用Python做日历?_第4张图片

有兴趣的同学可以去看看。也希望这一点能给正在学习python的你一些感想。

已经到底啦~(≧▽≦*)/~

65b6ad15eec2bd51be3444f8e40e5838.png 往 期 推 荐 6937c1e0fe594cba56020089dd106714.png

年会将近?赶紧学学如何用Python做个抽奖界面

2022-01-02

如何用Python做日历?_第5张图片

用Python写份【幸运】的元旦祝福

2021-12-31

如何用Python做日历?_第6张图片

Python自动化办公:xlwt万字教程

2021-12-20

如何用Python做日历?_第7张图片

Python自动化办公:xlwt教程(二)

2021-12-23

如何用Python做日历?_第8张图片

如何用Python做日历?_第9张图片

您的“点赞”、“在看”和 “分享”是我们产出的动力。

你可能感兴趣的:(列表,python,数据分析,github,人工智能)