• 作者:老汪软件技巧
  • 发表时间:2024-09-02 00:04
  • 浏览量:

下半年的假期

今天妹妹写作业的时候,我观察到她愁眉不展,我问她怎么了,她说,“快开学了,可是,我不喜欢开学,我想要放假,什么时候才能放假啊?”

啊这,确实,因为9月份,10月份节日调休的原因,下两个月的假期确实很混乱。如果不看日历的话,还真容易搞不清楚哪天休息,于是,我打开了一份日历,我发现,日历网站上面全是广告啊,从出行航班到入住酒店一应俱全。唉,看别人的日历不如自己制作一份日历。因此,我决定通过python编程,自己打印一份日历!

python自制日历需要的库

import calendar
import datetime
from termcolor import colored

首先,我们知道,正常情况下,周一至周五应该是工作日,周六和周日是休息日,但是,遇到一些节日的时候,周六和周日也可能变成工作日,而周一至周五也可能变成休息日,这怎么办呢!很简单,我们只需要标记所有的“特殊日子”就行了,只需要这样:

months=12
special_days = {
    datetime.date(2024, 1, 1): "holiday",  # 元旦休息
    datetime.date(2024, 2, 4): "workday",  # 春节调休
    datetime.date(2024, 2, 10): "holiday",  # 春节休息
    datetime.date(2024, 2, 11): "holiday",  # 春节休息
    datetime.date(2024, 2, 12): "holiday",  # 春节休息
    datetime.date(2024, 2, 13): "holiday",  # 春节休息
    datetime.date(2024, 2, 14): "holiday",  # 春节休息
    datetime.date(2024, 2, 15): "holiday",  # 春节休息
    datetime.date(2024, 2, 16): "holiday",  # 春节休息
    datetime.date(2024, 2, 17): "holiday",  # 春节休息
    datetime.date(2024, 2, 18): "workday",  # 春节调休
    datetime.date(2024, 4, 4): "holiday",  # 清明休息
    datetime.date(2024, 4, 5): "holiday",  # 清明休息
    datetime.date(2024, 4, 6): "holiday",  # 清明休息
    datetime.date(2024, 4, 7): "workday",  # 清明调休
    datetime.date(2024, 4, 28): "workday",  # 劳动调休
    datetime.date(2024, 5, 1): "holiday",  # 劳动休息
    datetime.date(2024, 5, 2): "holiday",  # 劳动休息
    datetime.date(2024, 5, 3): "holiday",  # 劳动休息
    datetime.date(2024, 5, 4): "holiday",  # 劳动休息
    datetime.date(2024, 5, 5): "holiday",  # 劳动休息
    datetime.date(2024, 5, 11): "workday",  # 劳动调休
    datetime.date(2024, 6, 10): "holiday",  # 端午休息
    datetime.date(2024, 9, 14): "workday",  # 中秋调休
    datetime.date(2024, 9, 15): "holiday",  # 中秋休息
    datetime.date(2024, 9, 16): "holiday",  # 中秋休息
    datetime.date(2024, 9, 17): "holiday",  # 中秋休息
    datetime.date(2024, 9, 29): "workday",  # 国庆调休
    datetime.date(2024, 10, 1): "holiday",  # 国庆休息
    datetime.date(2024, 10, 2): "holiday",  # 国庆休息
    datetime.date(2024, 10, 3): "holiday",  # 国庆休息
    datetime.date(2024, 10, 4): "holiday",  # 国庆休息
    datetime.date(2024, 10, 5): "holiday",  # 国庆休息
    datetime.date(2024, 10, 6): "holiday",  # 国庆休息
    datetime.date(2024, 10, 7): "holiday",  # 国庆休息
    datetime.date(2024, 10, 12): "workday"  # 国庆调休
    }

很好,我们得到了一点点的特殊日子标记。现在,我们就可以根据常规规则和特殊标记,检测一天是否是“工作日”了,只需要像这样:

def day_status(date, special_days):
    if date in special_days:
        return special_days[date]
    if date.weekday() >= 5:  # weekday()方法中周一为0,周日为6
        return "holiday"
    else:
        return "workday"

再然后,我们只需要根据一天是不是工作日,简单的将工作日打印为黑色,将休息日打印为红色就可以了,只需要像这样:

def print_colored_month(year, month):
    
    print()
    print(f"{year}{month}月")
    print()
    
    days = "一 二 三 四 五 六 日"
    print(days)
    month_range = calendar.monthrange(year, month)
    first_weekday, number_of_days = month_range
    padding = "   " * first_weekday
    print(padding, end='')
    for day in range(1, number_of_days + 1):
        date = datetime.date(year, month, day)
        status = day_status(date, special_days)
        if status == "holiday":
            print(colored(f"{day:2}", "red"), end=' ')  # 将休息日打印为红色
        else:
            print(f"{day:2}", end=' ')  # 将工作日打印为黑色
        if (first_weekday + day) % 7 == 0:
            print()
    if (first_weekday + number_of_days) % 7 != 0:
        print()
        
for months in range(int(months)):
    print_colored_month(2024,months+1)

现在,我们就得到了日历了

从这里,我们可以看出,假期较为混乱的实际上只有9月份,其中9月第二周的周六和第四周的周日,不是休息日!而11月份和12月份则是非常标准的休息日(啊,这岂不是说明,从10月以后,今年就没有假期了,悲)

需要注意的是,由于2025年尚未确定要如何调休,因此,目前我们的程序还不能够打印出2025年以后的日历,但是没关系,等到了2025年及以后,你只需要简单的修改我们之前定义的special_days,将其改为满足新的要求的调休计划,就可以很好的打印出新的日历了!

日历app显示调休__日历带调休

特殊日子倒计时

妹妹提醒我,“光有一个日历怎么行呢?还要有倒计时功能才能清楚的知道还有多少天能等到。我看到隔壁的大哥哥们都有考试倒计时,比如说,我看到他们总是挂着,距离高考还有1天。对啊?他们为什么总是还有1天啊?“

唉,这大概是因为,考试以前天天都有人会更换数字,而等到了真的考试的时候,就没在这里插入代码片有人在学校了,也没有人会去更换数字了,要一直等到下一年用倒计时的时候,才会有人重新使用它们吧。不过,妹妹说的很对,我们应该提供倒计时的功能。

倒计时的功能很容易实现,我们只需要使用python的datetime库计算出时间差就可以实现了。说到datetime库的使用,有一位热心博主写的特别好,/post/702743…,我们可以进行一下简单的参考。

首先,我们还是需要知道,有哪些需要添加到倒计时中的日子,注意!你也可以在这里添加对你来说特别重要的日子,在这里,我添加了亿点点:

events = {
    datetime.date(2024, 9, 17): "中秋节",
    datetime.date(2024, 10, 1): "十一国庆",
    datetime.date(2024, 11, 1): "万圣节",
    datetime.date(2024, 11, 11): "双十一",
    datetime.date(2024, 12, 12): "双十二",
    datetime.date(2024, 12, 25): "圣诞节",
    datetime.date(2025, 1, 1): "元旦",
    datetime.date(2025, 1, 7): "腊八",
    datetime.date(2025, 1, 28): "除夕",
    datetime.date(2025, 1, 29): "春节"
}

小帖士:美国的感恩节是11月的第四个星期四,而加拿大的感恩节是10月的第二个星期一,比美国的感恩节早约一个半月。在游戏饥荒中,有一个叫做伍迪的角色(就是会变身的伐木工啦),他在加拿大地区时会显示为“在适当的时候过感恩节”,而在美国地区会显示为“太早过感恩节”,在世界其他地区则会显示为“对丰收心怀感恩”。这就是因为,美国的感恩节和加拿大的感恩节不是同一天。不过嘛,由于感恩节在我们这里似乎不怎么受关注,因此,我没有将其放进倒计时中。

然后,我们需要有一个,能够计算倒计时的功能,实际上,就是用目标时间减去今天,算出时间差啦:

def count_down(event_date, event_name):
    today = datetime.date.today()
    delta = event_date - today
    return delta.days, event_name

然后,我们只需要算出每个日子还有多少天就可以了:

for event_date, event_name in events.items():
    days_left, name = count_down(event_date, event_name)
    print(f"距离{name}还有{days_left}天!")

不过,我们还需要适当的处理一下已经过完的日子(比如说,我们可能不希望看见距离开学还有-10天),以及如果我们没按顺序添加日子的话,显示的倒计时不按顺序的问题,只需要:

for event_date, event_name in sorted(events.items(), key=lambda x: x[0]):
    days_left, name = count_down(event_date, event_name)
    if days_left > 0:
        print(f"距离{name}还有{days_left}天!")

此时,就能看到运行结果了(运行的时间为2024年9月1日):