在美國,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。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 日星期五。
發布於 。
後續步驟
建立免費金鑰,從自己的程式碼呼叫 API。 取得免費 API 金鑰
