Python实现节假日及按规定的加班日期

需求:因每月1-3号以及上月末最后1天共4天必须上班。现需要用Python编写一段程序判断某年需要加班的日期,需要考虑元旦,五一,十一假期。还需要考虑输入年份是否为平闰年,判断对应2月的天数。
(放假规则说明:
如五月1日:
在周一,则休息日为上周六七及本周一,无需补班。
在周二,则休息日为上周日加本周一二,上周六需补班。
在周三,则休息日为二三四,休假前的周日与休假后的周六各补班一天。
在周四,则休息日为四五六,本周日需要补班。
在五六日,则休息日为五六日,不需补班。

元旦与劳动节规则一样。

十月一日:
每年固定休假为1-7日。
如1号在周一,则上周六七需要补班,
其它则需要在假期前一周周六及假期后一周周末各补班1天。

其余月份则判断是否在周末决定是否需要加班。
)

结果:
1.展现某年需要加班的日期。
2.展示元旦,五一,十一的假期日期和补班日期

注:(扩展)需要考虑程序灵活性及可扩展性(如休假日期改为月末最后2天和月初2天,或者指定端午等农历节日对应的阳历,展示对应休假日期).

代码编程主要逻辑:
1.先定义一个字典,然后对字典进行排序:
注:这里对字典排序写的不是很好,因为当时还不会key=lambda排序。所以对月份1月写1,而不是01。(这里是个坑,因为在后续生成当年是日期的时候又处理的很啰嗦,专门又给1转换为了01.)

dict_date = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
sorted(dict_date)

2.定义函数,判断是否为闰年,如果是闰年,将对2月28日改为29。然后根据当年的第几天,生成对应的日期。如:1,生成的日期为20190101。

def int_t_date(daycnt, year='2019 '):
    """
    根据天数返回当年的日期
    :param daycnt:
    :param year:
    :return:
    """
    # 判断是否为闰年
    if int(year) % 100 == 0:
        if int(year) % 400 == 0:
            dict_date[2] = 29
        else:
            pass
    elif int(year) % 4 == 0:
        dict_date[2] = 29
    else:
        pass
    month = 0
    day = 0
    cnt = 0
    for x, y in dict_date.items():
        cnt += y
        if cnt < int(daycnt):
            pass
        elif cnt == int(daycnt) and x == 1:
            month = x
            day = int(daycnt)
            break
        else:
            month = x
            day = int(daycnt) - cnt + y
            break
    if len(str(month)) == 1 and len(str(day)) == 1:
        return str(year) + "0" + str(month) + "0" + str(day)
    elif len(str(month)) == 1:
        return str(year) + "0" + str(month) + str(day)
    elif len(str(day)) == 1:
        return str(year) + str(month) + "0" + str(day)
    else:
        return str(year) + str(month) + str(day)

3.定义函数传入列表日期,判断每年的加班日期,结果存入到列表jbrq中:
注:这就是当时的坑,因为定义列表排序问题,导致单独处理日期,进行拼接0。

def jbsd_ls(list_day, current_year):
    """
    取出每月加班时段
    :param list_day:
    :param current_year:
    :return:
    """
    if list_day[-1][6:] in ['01']:
        if list_day[-1][4:] == '0101':
            # 对于每年1月1日进行特殊处理取前一年年底
            jbrq = list_day[-1:]
            jbrq.insert(0, str(int(current_year) - 1) + '1231')
            jbrq.insert(2, str(int(list_day[-1]) + 1))
            jbrq.insert(3, str(int(list_day[-1]) + 2))
            return jbrq
        else:
            jbrq = list_day[-2:]
            jbrq.insert(2, str(int(list_day[-1]) + 1))
            jbrq.insert(3, str(int(list_day[-1]) + 2))
            return jbrq

4.判断法定节假日为3天假期的放假规则(元旦除外,因为元旦可能涉及到前1年的天数):

def check_holiday_3(list_a, list_day):
    """
    对于法定节假日判断放假日期及补班日期(元旦、国庆、春节除外)
    :param list_a:
    :param list_day:
    :param jbsd:
    :return:
    """
    week = datetime.datetime.strptime(list_a, "%Y%m%d").weekday()
    if week == 0:  # 周一
        print("不需补班")
        print("放假日期为:" + str(list_day[-3:]))  # 如果1月1日在周一,不需要调休,正常连接周六日放假
        return list_day[-3:]
    elif week == 1:  # 周二
        print("补班日期为:" + str(list_day[-4]))
        print("放假日期为:" + str(list_day[-3:]))
        return list_day[-3:]
    elif week == 2:  # 周三
        print("补班日期为:" + str(list_day[-4]) + " 和 " + str(int(list_a) + 3))
        ls = list_day[-2:]
        ls.append(str(int(list_a) + 1))
        print("放假日期为:" + str(ls))
        return ls
    elif week == 3:  # 周四
        print("补班日期为:" + str(int(list_a) + 3))
        ls = list_day[-1:]
        ls.append(str(int(list_a) + 1))
        ls.append(str(int(list_a) + 2))
        print("放假日期为:" + str(ls))
        return ls
    elif week == 4:  # 周五
        print("不需补班")
        ls = list_day[-1:]
        ls.append(str(int(list_a) + 1))
        ls.append(str(int(list_a) + 2))
        print("放假日期为:" + str(ls))
        return ls
    elif week == 5:  # 周六
        print("不需补班")
        ls = list_day[-2:]
        ls.append(str(int(list_a) + 1))
        print("放假日期为:" + str(ls))
        return ls
    else:  # 周日
        print("不需补班")
        print("放假日期为:" + str(list_day[-3:]))
        return list_day[-3:]

5.判断法定节假日为7天假期的放假规则函数(check_holiday_7)(这里有个小坑,就是当输入的春节日期为年底最后6天或者年初前6天的时候后,程序会出错,目前还没见过春节和元旦离得特别近,所以懒得处理,有兴趣的小伙伴可以试一下。)

和放假3天类似,同志们仿照3天的方法编写。
def check_holiday_7(list_a, list_day):
    """
    对于国庆节,春节这些节日进行判断
    :param list_a:
    :param list_day:
    :return:
    """
    week = datetime.datetime.strptime(list_a, "%Y%m%d").weekday()
    b = list(range(int(list_day[-1]), int(list_day[-1]) + 7))
    #list_scq = [x for x in b]
    list_scq = []
    ...
    ...
    ...
    ...

6.对于元旦生成元旦的放假日期函数(check_holiday_1_1):

def check_holiday_1_1(list_a, jbsd, current_year):
    """
    判断每年元旦放假日期
    :param list_a:
    :param list_day:
    :param jbsd:
    :param current_year:
    :return:
    """
    week = datetime.datetime.strptime(list_a, "%Y%m%d").weekday()
    if week == 0:  # 周一
    以下自行编写
    ...
    ...
    ...

7判断加班时段是否在放假日期中函数:

def overdate(jbsd, add_day):
    """
    判断加班时段是否在节假日
    :param jbsd:
    :param add_day:
    :return:
    """
    list_ = ''#list_代表自定义变量
    for i in jbsd:
        if i in add_day:
            list_ += str(i) + ';'
    return list_

8.对于扩展项目,对农历传统节日判断,我这里直接用的input,用户自定输入农历对应的阳历日期,然后程序进行判断放假规则。

 current_year = input("请输入春节对应的阳历日期(如:2019):")
    holiday_ls = []
    holiday_cj = input("请输入春节对应的阳历日期(如:20190205):")
    holiday_ls.append(holiday_cj)
    holiday_qm = input("请输入清明对应的阳历日期(如:20190404):")
    holiday_ls.append(holiday_qm)
    holiday_dw = input("请输入端午对应的阳历日期(如:20190505):")
    holiday_ls.append(holiday_dw)
    holiday_zq = input("请输入中秋对应的阳历日期(如:20190815):")
    holiday_ls.append(holiday_zq)
    holiday_qt = input("请输入特殊活动统一放假日期(如:20190129):")
    holiday_ls.append(holiday_qt)
    holiday_ls.extend([current_year + '0101', current_year + '0501', current_year + '1001'])

9.main函数对逻辑进行总体判断:

1. input输入农历对应的阳历日期。
2. 先判断闰年。进行修改天数。
3. 循环当年的总天数,比365,每次循环,调用函数int_t_date。生成对应的日期。
4. 通过最新生成的日期判断是否为加班日期,通过调用函数jbsd_ls。
5. 判断日期是否在法定节假日中,然后根据规则判断是放3天还是7天。存入到add_day列表中.
6. 判断加班,如果是元旦,进行单独处理。
7. 其他月份判断日期是否在加班日期中,如果在,那么需要加班,如果不在,那就判断日期是否为周六日,如果是,不加班。

结果如下:

请输入春节对应的阳历日期(如:2019):2019
请输入春节对应的阳历日期(如:20190205):20190205
请输入清明对应的阳历日期(如:20190404):
请输入端午对应的阳历日期(如:20190505):
请输入中秋对应的阳历日期(如:20190815):20190815
请输入特殊活动统一放假日期(如:20190129):
01月
补班日期为:20181229
放假日期为:['20181230', '20181231', '20190101']
加班日期20181231;20190101;
02月
加班日期:20190202
加班日期:20190203
补班日期为:2019020320190216
放假日期为:[20190205, 20190206, 20190207, 20190208, 20190209, 20190210, 20190211]
03月
加班日期:20190302
加班日期:20190303
04月
加班日期:20190331
补班日期为:2019042820190504
放假日期为:['20190430', '20190501', '20190502']
05月
加班日期20190430;20190501;20190502;
加班日期20190430;20190501;20190502;
加班日期20190430;20190501;20190502;
06月
加班日期:20190601
加班日期:20190602
07月
加班日期:20190630
08月
加班日期:20190803
补班日期为:20190818
放假日期为:['20190815', '20190816', '20190817']
09月
加班日期:20190831
加班日期:20190901
补班日期为:2019092920191012
放假日期为:[20191001, 20191002, 20191003, 20191004, 20191005, 20191006, 20191007]
10月
加班日期20191001;20191002;20191003;
加班日期20191001;20191002;20191003;
加班日期20191001;20191002;20191003;
11月
加班日期:20191102
加班日期:20191103
12月
加班日期:20191130
加班日期:20191201

-end-

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值