跳过休息日(周末和节假日)

日期计算跳过周末

使用pandas计算一定日期内工作日的天数,周末天数,遇到周末向后延长对应天数

例如
'2022-06-2’到’2022-06-04’之间有一天不是工作日

def skip_weekend(start_date='2022-06-20', end_date='2022-06-27'):
    """跳过周末(忽略节假日)"""
    import datetime
    import arrow
    import pandas as pd
    if not isinstance(end_date, datetime.date):
        end_date = arrow.get(end_date).date()
    if not isinstance(start_date, datetime.date):
        start_date = arrow.get(start_date).date()
    everyday = (end_date - start_date).days + 1  # 每天
    weekday = len(pd.bdate_range(start_date, end_date))  # 工作日
    day_off = everyday - weekday  # 休息日

    new_start_date = arrow.get(end_date).shift(days=+1).date()
    new_end_date = arrow.get(end_date).shift(days=+day_off).date()

    def over_day(new_start_date, new_end_date, day_off):
        print(new_start_date, new_end_date, day_off)
        weekday = len(pd.bdate_range(new_start_date, new_end_date))
        print(weekday)
        new_day_off = day_off - weekday
        print(day_off)
        if new_day_off != 0:
            new_end_date = arrow.get(new_end_date).shift(days=+new_day_off).date()
            return over_day(new_start_date, new_end_date, day_off)
        return new_start_date, new_end_date, day_off

    new_start_date, new_end_date, day_off = over_day(new_start_date, new_end_date, day_off)
    return start_date, new_end_date

实例

a, b = skip_days_off('2022-06-2', '2022-06-4')

print(a, b)

输出结果

2022-06-02 2022-06-06

日期计算跳过休息日(包含周末和节假日)

使用pandas 自定义节假日规则,补班规则,一定日期内遇到节假日或者周末延后对应天数
例如
2022-10-012022-10-07 中间有 7天休息日;而且10月8日(星期六)、10月9日(星期日)上班

"""
获取地址:https://www.gov.cn/zhengce/content/2021-10/25/content_5644835.htm

一、元旦:2022年1月1日至3日放假,共3天。

二、春节:1月31日至2月6日放假调休,共7天。1月29日(星期六)、1月30日(星期日)上班。

三、清明节:4月3日至5日放假调休,共3天。4月2日(星期六)上班。

四、劳动节:4月30日至5月4日放假调休,共5天。4月24日(星期日)、5月7日(星期六)上班。

五、端午节:6月3日至5日放假,共3天。

六、中秋节:9月10日至12日放假,共3天。

七、国庆节:10月1日至7日放假调休,共7天。10月8日(星期六)、10月9日(星期日)上班。
"""

import arrow
import pandas as pd
from pandas.tseries.offsets import CustomBusinessDay
import datetime


class SkipDaysOff:
    # 假期规则 国务院每年会发放假期通知 http://www.gov.cn/
    year = str(arrow.now().date().year)  # 当前年份
    holiday_rules = [year + '-01-01', year + '-01-02', year + '-01-03',
                     year + '-01-31', year + '-02-01', year + '-02-02', year + '-02-03', year + '-02-04',
                     year + '-02-05', year + '-02-06',
                     year + '-04-03', year + '-04-04', year + '-04-05',
                     year + '-04-30', year + '-05-01', year + '-05-02', year + '-05-03', year + '-05-04',
                     year + '-06-03', year + '-06-04', year + '-06-05',
                     year + '-09-10', year + '-09-11', year + '-09-12',
                     year + '-10-01', year + '-10-02', year + '-10-03', year + '-10-04', year + '-10-05',
                     year + '-10-06', year + '-10-07']
    # 额外工作日
    extra_workday = [year + '-01-29', year + '-01-30', year + '-04-02', year + '-04-24', year + '-05-07',
                     year + '-10-08', year + '-10-09']
    c = CustomBusinessDay(holidays=holiday_rules)

    def count_workday(self, start_day, end_day):
        """返回工作日天数,和休息日天数"""
        everyday = [i.strftime('%Y-%m-%d') for i in arrow.Arrow.range('day', start_day, end_day)]
        workday = len(pd.date_range(start=start_day, end=end_day, freq=self.c))
        extra_workday_len = len(set(everyday) & set(self.extra_workday))
        workday_num = workday+extra_workday_len
        day_off_num = len(everyday) - workday_num
        return workday_num, day_off_num

    def skip_days_off(self, start_date='2022-06-20', end_date='2022-06-27'):
        """跳过休息日 结束日期=原结束日期+休息日(天数)"""
        if not isinstance(end_date, datetime.date):
            end_date = arrow.get(end_date).datetime
        if not isinstance(start_date, datetime.date):
            start_date = arrow.get(start_date).datetime

        # 休息日天数
        day_off = self.count_workday(start_date, end_date)[1]

        # 新增加天数的开始时间
        new_start_date = arrow.get(end_date).shift(days=+1).datetime
        # 新增加天数的结束时间
        new_end_date = arrow.get(end_date).shift(days=+day_off).datetime

        def over_day(new_start_date, new_end_date, day_off):
            """
            新结束时间将一直增加新休息日;
            新增加天数中工作日天数等于缺少的休息日天数时,结束
            """
            weekday = self.count_workday(new_start_date, new_end_date)[0]
            new_day_off = day_off - weekday
            if new_day_off != 0:
                new_end_date = arrow.get(new_end_date).shift(days=+new_day_off).datetime
                return over_day(new_start_date, new_end_date, day_off)
            return new_start_date, new_end_date, day_off
        new_start_date, new_end_date, day_off = over_day(new_start_date, new_end_date, day_off)
        return start_date.date(), new_end_date.date()

实例

a, b = SkipDaysOff().skip_days_off('2022-10-01', '2022-10-07')

print(a, b)

输出结果

2022-10-01 2022-10-14

输出结果将,额外的工作日也计算进去了,跳过n天休息日,增加n天工作日

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
判断节假日休息日的方法有很多种,下面介绍两种常用的方法: ## 方法一:调用第三方 API 可以使用第三方 API 来判断一个日期是否为节假日或者休息日,例如阿里云的节假日 API。 使用方法如下: 1. 首先注册阿里云账号,并开通节假日 API 的服务; 2. 调用 API 的接口,传入需要判断的日期和 API 的appcode,即可得到判断结果。 示例代码如下: ```python import requests def is_holiday(date): """ 判断日期是否为节假日 :param date: 日期,格式为 'YYYY-MM-DD' :return: True 或者 False """ url = "http://tool.bitefu.net/jiari/" headers = {"Authorization": "APPCODE your_appcode_here"} res = requests.get(url + "?d=" + date, headers=headers) if res.status_code == 200: return True if res.text == '1' else False else: return False # 测试代码 print(is_holiday('2021-10-01')) # True print(is_holiday('2021-10-04')) # False print(is_holiday('2021-10-09')) # True ``` ## 方法二:使用本地数据 如果不想调用 API,也可以使用本地数据来判断日期是否为节假日或者休息日。 使用方法如下: 1. 获取节假日休息日的数据,可以从官方网站或其他可信渠道下载; 2. 将数据保存到本地,例如保存到一个 JSON 文件中; 3. 在代码中读取 JSON 文件,判断日期是否为节假日或者休息日。 示例代码如下: ```python import json def is_holiday(date): """ 判断日期是否为节假日 :param date: 日期,格式为 'YYYY-MM-DD' :return: True 或者 False """ with open('holiday_data.json', 'r') as f: data = json.load(f) if date in data['holiday']: return True if date in data['workday']: return False week_day = datetime.datetime.strptime(date, '%Y-%m-%d').weekday() if week_day >= 5: return True return False # 测试代码 print(is_holiday('2021-10-01')) # True print(is_holiday('2021-10-04')) # False print(is_holiday('2021-10-09')) # True ``` 在代码中,我们使用了 `json` 库来读取 JSON 文件中的数据。然后,我们定义了一个 `is_holiday` 函数,用来判断输入的日期是否为节假日或者工作日。在测试代码中,我们输入了三个日期进行测试,输出结果与预期一致。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值