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

日期计算跳过周末

使用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天工作日

### 如何在项目管理软件的甘特图中配置跳过节假日 #### MindManager 中设置特殊假日 对于像春节这样的特殊节日,MindManager 提供了灵活的方式来进行处理。当创建时间表类型的思维导图并切换到甘特视图时,默认情况下已经区分了工作日周末。然而,针对特定的公共假期或公司内部放假安排,则需手动调整。 - **添加非工作时段**:可以通过自定义日历来实现这一点。进入“工具”菜单下的选项设置里找到关于工作时间的部分,这里允许指定哪些日期应被标记为不工作的日子[^1]。 ```python # 假设有一个函数用于设定非工作日列表 def set_non_working_days(holiday_list): for day in holiday_list: mindmanager_calendar.mark_as_holiday(day) holiday_list = ["2023-01-21", "2023-01-22"] # 春节期间的具体休息日 set_non_working_days(holiday_list) ``` #### WPS 表格中的考虑事项 虽然WPS表格也可以用来构建简单的甘特图表来跟踪进度,但它不具备内置的日历功能去识别具体的节假日。因此,在这种环境下想要绕过某些天数的话,可能就需要依靠外部的数据源或者是通过公式计算排除掉这些日期的影响[^2]。 #### 使用 DHTMLX Gantt 设置全局日历 如果采用的是基于Web的应用程序如DHTMLX Gantt库开发定制化解决方案,则可以直接利用其强大的API接口完成此操作。这涉及到修改默认的工作模式以及引入额外的日程条目代表特别事件(比如法定假日),从而确保它们不会影响任务计划的实际执行周期[^3]。 ```javascript // 定义一个包含所有中国国定假日的对象数组 var holidays = [ {start_date:"2023-01-21", end_date:"2023-01-27"}, // 春节假期限定 ]; gantt.init("gantt_here"); gantt.config.work_time = false; // 关闭标准工时检测以便我们可以完全控制可用性 for (let i=0;i<holidays.length;i++){ gantt.addHoliday(new Date(holidays[i].start_date), new Date(holidays[i].end_date)); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值