在程式碼中加入假日檢查

每年擷取一次各國假日日期,存入集合後,再用它檢查日期。以 2026 年為例,全年只需一次請求,無須為每個日期各發出一次請求。依此規則,2026 年 11 月 27 日星期五是工作日;2026 年 11 月 26 日星期四是感恩節,因此不是工作日。工作日必須不是星期六或星期日,且不在假日集合中。

使用 API

GET /v1/calendars/holidays/{country}/{year} 會回傳全年資料。依國家和年份快取回傳的 date 字串,讓處理數千個日期的工作對每個國家與年份組合只發出一次請求。請在快取中一併保留國家和年份:使用的集合必須符合傳入函式的日期。

  1. 設定你的 API 金鑰 取得免費金鑰,並存放在 NARWHAL_API_KEY 環境變數中。指令碼會讀取該變數,並以 Authorization: Bearer YOUR_KEY 將金鑰傳送至 https://api.narwhalapi.com。
  2. 使用有快取的 Python 函式 函式會將假日字串存入 frozenset,並以國家和年份作為快取引數。請用 Python 的 date 呼叫 is_business_day;預設國家為 USA,遇到週末時會在查詢假日前回傳 False。
    Python,有快取的工作日檢查
    import os
    from datetime import date
    from functools import lru_cache
    import requests
    
    HEADERS = {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"}
    
    
    @lru_cache(maxsize=None)
    def holiday_dates(country: str, year: int) -> frozenset[str]:
        r = requests.get(
            f"https://api.narwhalapi.com/v1/calendars/holidays/{country}/{year}",
            headers=HEADERS,
            timeout=10,
        )
        r.raise_for_status()
        return frozenset(h["date"] for h in r.json()["holidays"])
    
    
    def is_business_day(day: date, country: str = "USA") -> bool:
        return day.weekday() < 5 and day.isoformat() not in holiday_dates(country, day.year)
    
    
    for d in (date(2026, 11, 26), date(2026, 11, 27), date(2026, 11, 28)):
        print(d, d.strftime("%a"), is_business_day(d))
  3. 在應用程式中使用 JavaScript 函式 在 JavaScript 中,映射會為每個國家與年份組合儲存一個集合,函式則接受 ISO 日期字串。需要預設 USA 以外的行事曆時,請傳入國家;日期存入快取前會先處理回應狀態。
    JavaScript (Node 18+),相同的檢查
    const headers = { Authorization: `Bearer ${process.env.NARWHAL_API_KEY}` };
    const cache = new Map();
    
    async function holidayDates(country, year) {
      const key = `${country}-${year}`;
      if (!cache.has(key)) {
        const res = await fetch(
          `https://api.narwhalapi.com/v1/calendars/holidays/${country}/${year}`,
          { headers },
        );
        if (!res.ok) throw new Error(`Narwhal ${res.status}`);
        cache.set(key, new Set((await res.json()).holidays.map((h) => h.date)));
      }
      return cache.get(key);
    }
    
    export async function isBusinessDay(isoDate, country = "USA") {
      const day = new Date(`${isoDate}T12:00:00Z`).getUTCDay();
      if (day === 0 || day === 6) return false;
      return !(await holidayDates(country, Number(isoDate.slice(0, 4)))).has(isoDate);
    }
    
    console.log(
      await isBusinessDay("2026-11-26"),
      await isBusinessDay("2026-11-27"),
      await isBusinessDay("2026-11-28"),
    );

免費方案每月有 5,000 次請求,因此工作需要處理大量日期時,應重複使用全年集合。

Python 的快取位於 holiday_dates;JavaScript 的快取則是函式外的 Map。兩者都將假日日期保存在記憶體中以供重複使用。應用程式需要時,再加入更新排程及檔案或資料庫儲存。若要每月更新當年度資料,並在重新啟動後保留日期,就需要在快取查詢中加入這些功能。

使用試算表或不寫程式的方式

在獨立的工作表分頁中保留假日欄,並在公式中使用 Holidays 作為範圍名稱。將要判斷的日期放在 A2。公式會結合平日檢查與該日期在假日範圍中的出現次數,讓試算表採用與指令碼相同的工作日規則。假日欄應與 API 快取一樣,包含要判斷的國家和年份的日期。用公式檢查其他日期時,請保留該欄供公式使用。

工作日公式
=AND(WEEKDAY(A2,2)<6, COUNTIF(Holidays, A2)=0)

平日只有在假日範圍內沒有相符日期時,才會回傳 TRUE。星期六或星期日即使不在該範圍內,也會回傳 FALSE。這種方式適合手動編輯假日日期的團隊:欄位保存日期,公式則判斷 A2 中的日期是否為工作日。

各種情況適合的方式

情況最適合的方式原因
指令碼或服務快取的集合在多次日期查詢中重複使用全年假日日期
經常重新啟動的應用程式包含年份並每年更新的檔案或資料表在應用程式重新啟動後保留假日集合
手動編輯日期的團隊試算表欄位使用團隊維護的假日日期

對經常重新啟動的應用程式,請將國家、年份和假日日期一併儲存。載入與待判斷日期相符的集合。持久儲存的集合與記憶體中的集合使用相同的假日清單檢查規則。

假日日期應該快取多久?

每月更新當年度資料,並在下一年度資料發布後擷取。假日行事曆很少變動,因此兩次更新之間可以重複使用全年集合。如果應用程式經常重新啟動,請將集合連同年份存入檔案或資料表,並每年更新。

不要快取失敗的回應。兩個指令碼都會在儲存假日日期前處理失敗的回應。Basic 或 Pro 的 Webhook 和串流可透過 holiday.calendar.revised 事件通知行事曆修訂。

日期應使用哪個時區?

請使用市場所在地時區的日曆日期。UTC 午夜在美洲可能仍是前一天,因此傳入函式的日曆日期會影響結果。傳入任一指令碼前,請先確認市場當地的日期;假日集合儲存的是日期字串,是否在集合內取決於你使用的日期字串。

Python 函式接受 date。JavaScript 函式接受 ISO 日期字串,並依其年份選取假日集合。兩者都不接受市場時區引數。

如果該年度尚未發布怎麼辦?

API 會回傳 404 calendar_not_published;請改用僅判斷週末的備援方式,並記錄此情況。使用此備援方式時,星期六和星期日仍不是工作日,平日則無須查詢假日就會通過。由於假日行事曆無法使用,此時平日的結果只取決於週末規則。

兩個函式都會在回應失敗時拋出錯誤。請在應用程式處理該錯誤的位置加入僅判斷週末的備援邏輯,並避免將尚未發布的回應存入假日快取。錯誤參考資料請見 API 錯誤。

實作範例:2026 年感恩節當週

先使用 2026 年 11 月 26 日星期四,以及 2026 年的 USA 行事曆。當天是平日,因此結果取決於日期是否在假日集合中。當天是美國感恩節,因此工作日判斷結果為 False。

接著查看 2026 年 11 月 27 日星期五。當天通過平日檢查,且不在假日集合中,因此結果為 True。2026 年 11 月 28 日星期六未通過平日檢查,無須查詢假日就會回傳 False。

日期星期工作日原因
2026年11月26日星期四False美國感恩節
2026年11月27日星期五True不在假日集合中的平日
2026年11月28日星期六False週末
2026 年感恩節當週的 Python 輸出
2026-11-26 Thu False
2026-11-27 Fri True
2026-11-28 Sat False
2026 年感恩節當週的 JavaScript 輸出
false true false

發布於 。

後續步驟