在美国,2026年11月20日星期五之后的第五个工作日是2026年11月30日星期一,因为需要跳过11月26日星期四的感恩节(不扣除该假日时,结果为11月27日星期五)。从所选日期之后开始,逐日向前,跳过周末和假日日期,直到经过所需的工作日天数。
使用 API 增加工作日
使用 GET /v1/calendars/holidays/{country}/{year} 获取计算所需国家和年份的假日日期。Python 函数将这些日期保存在一个集合中,并逐日与集合比较。只有属于周一至周五且不在假日集合中的日期才会计数。跳过日期时,剩余工作日天数保持不变。
- 设置你的 API 密钥 获取免费 API 密钥,并将其保存在环境变量
NARWHAL_API_KEY中。脚本读取该变量,并通过Authorization: Bearer YOUR_KEY将密钥发送至https://api.narwhalapi.com。 - 选择开始日期和国家 将开始日期、要增加的工作日天数和国家代码传给
add_business_days;函数默认使用USA。开始日期为第0天,因此函数先向前移动一天,再判断该日期是否计入总数。 - 运行计算 要计算美国2026年11月20日星期五之后的第五个工作日,请使用脚本末尾的调用。跳过周末和2026年11月26日星期四的感恩节后,脚本输出
2026-11-30。Python,在日期上增加工作日import os from datetime import date, timedelta import requests API = "https://api.narwhalapi.com" HEADERS = {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"} def holidays(country: str, year: int) -> set[str]: r = requests.get(f"{API}/v1/calendars/holidays/{country}/{year}", headers=HEADERS, timeout=10) r.raise_for_status() return {h["date"] for h in r.json()["holidays"]} def add_business_days(start: date, n: int, country: str = "USA") -> date: off, loaded, day = set(), set(), start while n > 0: day += timedelta(1) if day.year not in loaded: off |= holidays(country, day.year) loaded.add(day.year) if day.weekday() < 5 and day.isoformat() not in off: n -= 1 return day print(add_business_days(date(2026, 11, 20), 5))
每次计算中,每个年份只加载一次。逐日计算进入1月1日时,函数先请求该年份的假日日历,再对该年的日期计数。loaded 集合记录已加载的年份,off 保存这些年份的假日日期。函数持续逐日向前,直到所需的工作日天数全部计完,然后返回到达的日期。
holidays 函数读取响应中的 holidays 数组,并提取每个条目的 date。逐日计算时,将这些值与 day.isoformat() 比较,并使用 day.weekday() 判断是否为周一至周五。两个条件都满足时,n 才会减少。落在周末的假日仍会被跳过:循环每次前进一个自然日,该日期不会减少剩余天数。返回值是计数完成时到达的日期。
使用 Excel 或 Google Sheets
在 Excel 或 Google Sheets 中,将2026年11月26日放入名为 Holidays 的范围,并将开始日期和工作日天数传给 WORKDAY。从2026年11月20日星期五增加五个工作日,公式返回2026年11月30日。假日范围提供除周末外需要跳过的日期,因此应包含本次计算适用的假日日期。
=WORKDAY(DATE(2026,11,20), 5, Holidays)将结果单元格设为日期格式。WORKDAY 返回序列号,单元格的日期格式会使结果显示为日历日期。如果计算采用其他周末安排,请使用 WORKDAY.INTL。开始日期、工作日天数和假日范围应与所需计算一致;公式使用你提供的假日日期。在示例公式中,DATE(2026,11,20) 提供开始日期,5 提供工作日天数。Holidays 指包含2026年11月26日的范围。如需在表格中使用其他开始日期,请修改开始日期输入,并提供适用的假日。
不同情况应选哪种方法
| 情况 | 最合适的方法 | 原因 |
|---|---|---|
| 单个日期 | 电子表格中的 WORKDAY | 在公式中提供开始日期、工作日天数和假日范围。 |
| 一列发票日期或数据库任务 | Python 脚本 | 将每个开始日期及对应的工作日天数传给函数。 |
| 其他国家的到期日期 | 传入该国家的代码 | API 请求使用所选国家的假日日历。 |
开始日期是节假日或周末时怎么办?
第1天是开始日期之后的第一个工作日。2026年11月28日星期六增加一个工作日,结果是2026年11月30日星期一:跳过星期日,星期一即为要增加的那个工作日。开始日期本身为假日时也适用同一规则。计数从该日期之后开始,过程中跳过周末和假日日期。
可以减去工作日吗?
可以。使用 timedelta(-1) 逐日向后计算并跳过周末和假日日期,或在电子表格中使用 =WORKDAY(start, -5, Holidays)。该公式使用提供的假日范围,从开始日期减去五个工作日。使用 Python 时,需修改函数使其向后计算;提供的脚本是向前计算的。
该年份尚未发布假日日历时怎么办?
API 对该国家和年份返回 404 calendar_not_published。脚本中的 raise_for_status() 会针对该响应抛出错误,因此提供的函数会在此停止。你可以修改函数,使其仅排除周末并标记结果,或稍后重试。如果仅排除周末,请标记返回的日期,明确说明计算如何处理假日。
计算示例:2026年11月20日星期五之后的第5个工作日
将2026年11月20日星期五作为第0天。跳过周末,将11月23日星期一、11月24日星期二和11月25日星期三分别计为第1、2和3个工作日。11月26日星期四是美国感恩节,因此计数保持为3。11月27日星期五是第4个工作日。
| 2026年的日期 | 处理方式 | 已增加的工作日天数 |
|---|---|---|
| 11月20日星期五 | 开始日期 | 0 |
| 11月21日星期六和22日星期日 | 跳过周末 | 0 |
| 11月23日星期一 | 计数 | 1 |
| 11月24日星期二 | 计数 | 2 |
| 11月25日星期三 | 计数 | 3 |
| 11月26日星期四 | 跳过感恩节 | 3 |
| 11月27日星期五 | 计数 | 4 |
| 11月28日星期六和29日星期日 | 跳过周末 | 4 |
| 11月30日星期一 | 计数并停止 | 5 |
跳过2026年11月28日星期六和29日星期日。11月30日星期一是第5个工作日,结果为 2026-11-30。如果不扣除感恩节假日,11月26日星期四将计为第4个工作日,11月27日星期五则为第5个工作日,结果将是2026年11月27日星期五。
发布于。
