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
相关产品推荐
相关产品推荐

