You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js实现:计算两日期区间内各月份的工作日天数

按月份拆分统计日期区间内的工作日天数

核心思路

把整个日期区间拆分成三部分处理:

  • 开始日期所在的月份:从开始日到当月最后一天
  • 中间的完整月份:每个月的1号到当月最后一天
  • 结束日期所在的月份:从当月1号到结束日

对每个子区间单独计算工作日(仅排除周六、周日,如需加入法定节假日可自行扩展),最后按月份格式输出结果。

Python 实现代码

import datetime
import calendar

def get_workdays_per_month(start_date_str, end_date_str, date_format="%d-%b-%Y"):
    # 解析输入日期
    start_date = datetime.datetime.strptime(start_date_str, date_format).date()
    end_date = datetime.datetime.strptime(end_date_str, date_format).date()
    
    workdays_by_month = {}
    
    # 处理开始月份
    start_month_last_day = datetime.date(start_date.year, start_date.month, calendar.monthrange(start_date.year, start_date.month)[1])
    current_end = start_month_last_day if start_month_last_day < end_date else end_date
    # 计算该区间工作日数
    workdays = 0
    for day in range((current_end - start_date).days + 1):
        current_day = start_date + datetime.timedelta(days=day)
        if current_day.weekday() < 5:  # 0-4对应周一到周五
            workdays += 1
    month_key = f"{start_date.strftime('%b')}'{start_date.strftime('%y')}"
    workdays_by_month[month_key] = workdays
    
    # 处理中间完整月份
    current_year = start_date.year
    current_month = start_date.month + 1
    while True:
        if current_year > end_date.year or (current_year == end_date.year and current_month > end_date.month):
            break
        # 获取当月第一天和最后一天
        first_day = datetime.date(current_year, current_month, 1)
        # 计算整月工作日数
        workdays = 0
        for week in calendar.monthcalendar(current_year, current_month):
            for day in week:
                if day != 0 and datetime.date(current_year, current_month, day).weekday() < 5:
                    workdays += 1
        month_key = f"{first_day.strftime('%b')}'{first_day.strftime('%y')}"
        workdays_by_month[month_key] = workdays
        # 月份递进
        if current_month == 12:
            current_month = 1
            current_year += 1
        else:
            current_month += 1
    
    # 处理结束月份(和开始月不同时才执行)
    if start_date.year != end_date.year or start_date.month != end_date.month:
        start_day = datetime.date(end_date.year, end_date.month, 1)
        workdays = 0
        for day in range((end_date - start_day).days + 1):
            current_day = start_day + datetime.timedelta(days=day)
            if current_day.weekday() < 5:
                workdays += 1
        month_key = f"{end_date.strftime('%b')}'{end_date.strftime('%y')}"
        workdays_by_month[month_key] = workdays
    
    return workdays_by_month

# 测试示例
result = get_workdays_per_month("20-Oct-2022", "14-Feb-2023")
for month, days in result.items():
    print(f"{month}为{days}天")

运行结果

Oct'22为8天
Nov'22为21天
Dec'22为22天
Jan'23为22天
Feb'23为10天

(注:示例中用户未提及Dec'22,实际该月完整工作日为22天,代码会自动包含区间内所有月份)

扩展说明

如果需要排除法定节假日,可以新增一个节假日列表,在计算工作日时额外判断当前日期是否在列表中,例如:

holidays = [datetime.date(2022, 12, 25), datetime.date(2023, 1, 1)]  # 示例节假日
# 在判断工作日时修改为:
if current_day.weekday() < 5 and current_day not in holidays:

内容的提问来源于stack exchange,提问作者Pramod Kulkarni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:15:27