为每个国家请求当年的节假日列表,把休息日收集到一个映射里,再读出所有国家都不休息的工作日。API 为每个国家和每一年提供一个节假日端点,所以跨四个国家的团队发四次请求,再用一个循环就能得到空闲的日子。
查询某个国家下一次休息是什么时候
GET /v1/calendars/holidays/{country}/next 返回 from_date 当天或之后的第一个节假日。这个请求查询日本从 2026 年 11 月 9 日起的情况。
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
"https://api.narwhalapi.com/v1/calendars/holidays/JPN/next?from_date=2026-11-09"{
"country": "JPN",
"coverage": [
{
"scope": "national_public",
"subdivision_codes": []
}
],
"holiday": {
"date": "2026-11-23",
"name": "Labor Thanksgiving Day",
"holiday_key": "labor_thanksgiving_day",
"local_name": "勤労感謝の日",
"scope": "national_public",
"subdivision_codes": []
}
}这个节假日是 11 月 23 日的勤劳感谢日,scope 为 national_public。local_name 是日文名称,holiday_key 是这类日子的稳定键。对单个国家来说,一次调用就能回答排期问题。对多个国家,可以逐个询问并保留最早的答案,或者像下一节那样读取整年的数据。
一次遍历找出各国的共同空闲日
- 获取 API 密钥 在注册页获取 API 密钥,并保存在
NARWHAL_API_KEY中。 - 列出国家和时间窗口 脚本使用
USA、DEU、JPN和IDN,在 11 月 9 日到 30 日之间寻找连续 3 个空闲的工作日。3 天只是示例,请换成你的发布或维护窗口所需的长度,也请按你自己的团队修改国家列表和日期。 - 收集休息日的日期 每个国家一次请求就返回当年的节假日。脚本把每个
date存入一个映射,键是日期,值是当天休息的国家集合。两个国家共有的日期会同时包含两个代码。 - 遍历工作日并输出报告 脚本先列出至少有一个国家休息的工作日,再找出第一段连续的空闲工作日。
import os from collections import defaultdict from datetime import date, timedelta import requests HEADERS = {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"} COUNTRIES = ["USA", "DEU", "JPN", "IDN"] START, END, NEED = date(2026, 11, 9), date(2026, 11, 30), 3 closed = defaultdict(set) # date -> countries closed that day for country in COUNTRIES: r = requests.get( f"https://api.narwhalapi.com/v1/calendars/holidays/{country}/{START.year}", headers=HEADERS, timeout=10, ) r.raise_for_status() for h in r.json()["holidays"]: closed[h["date"]].add(country) days, day = [], START while day <= END: if day.weekday() < 5: days.append((day, sorted(closed.get(day.isoformat(), [])))) day += timedelta(1) for day, who in days: if who: print(day.strftime("%a %d %b"), "closed:", ", ".join(who)) for i in range(len(days) - NEED + 1): if all(not who for _, who in days[i:i + NEED]): print(f"first {NEED} clear business days in a row start:", days[i][0].strftime("%a %d %b")) break
Wed 11 Nov closed: USA
Mon 23 Nov closed: JPN
Thu 26 Nov closed: USA
first 3 clear business days in a row start: Thu 12 Nov在 11 月 9 日到 30 日的 16 个工作日里,有 3 天存在休息,13 天在四个国家都是空闲的。连续 3 个空闲工作日的第一段从 11 月 12 日星期四开始。脚本没有使用 scope 过滤,所以印度尼西亚的集体休假日会被算作休息日。要把它们排除,可以在该国的请求中加上 scope=national_public。
排期时要避开的休息日
| 日期 | 国家 | 假日 |
|---|---|---|
| 11 月 11 日(周三) | USA | 退伍军人节 |
| 11 月 23 日(周一) | JPN | 劳动感谢日 |
| 11 月 26 日(周四) | USA | 感恩节 |
把发布安排在 11 月 11 日星期三,会撞上休息的美国办公室。两个感恩节是不同国家的不同节假日,holiday_key 的值分别是 labor_thanksgiving_day 和 thanksgiving_day,各自只让自己的国家休息。按键而不是名称匹配,就能把它们区分开。
想让排期的人直接看到休息日,可以通过 POST /v1/calendars/subscriptions 创建日历订阅源,把 include_holidays 设为 true,include_releases 设为 false。请求的说明见日历订阅文档。因为这个调用会创建订阅源,所以本页没有运行它。
在这次对比中各个 scope 涵盖的范围
| 国家 | 列表包含什么 | 对排期的影响 |
|---|---|---|
| USA | federal_government 范围 | 退伍军人节和感恩节显示为休息 |
| JPN | national_public 范围 | 勤劳感谢日显示为休息 |
| DEU | national_public 范围 | 这个时间窗口内没有休息日 |
| IDN | national_public 和 collective_leave | 这个时间窗口内没有休息日 |
依赖列表之前,先读每个响应中的 coverage。它写明了日历涵盖的 scope 和行政分区,而 scope 因国家而异。对于条目带有分区代码的国家,例如英国,还要多做一次检查:当条目的列表为空,或包含办公室所在的地区时,才保留该条目。
周末的节假日对排期有影响吗?
对遍历工作日的做法没有影响。脚本只看周一到周五,所以落在周六或周日的节假日会被跳过。有些国家会把假期顺延到工作日,并在新条目上标记 observed;该条目的日期是工作日,所以会显示为休息。
如果团队所在的国家有地区性节假日怎么办?
年度端点没有地区参数,所以要在你的代码里按 subdivision_codes 过滤。列表为空表示该节假日全国通用。在英国,每个银行假日对每组国家各出现一次,所以同一个日期可能有多个条目。
跨年的时间窗口需要多少次请求?
每个国家每一年一次请求。跨越 12 月 31 日的窗口,还需要每个国家下一年的列表;没有发布日历的年份会返回代码为 calendar_not_published 的 404。做长期排期时要预先处理这个响应,并把每一年的列表缓存起来,这样重复运行就不用再请求。
发布于。