避开多国节假日安排会议和发布

为每个国家请求当年的节假日列表,把休息日收集到一个映射里,再读出所有国家都不休息的工作日。API 为每个国家和每一年提供一个节假日端点,所以跨四个国家的团队发四次请求,再用一个循环就能得到空闲的日子。

查询某个国家下一次休息是什么时候

GET /v1/calendars/holidays/{country}/next 返回 from_date 当天或之后的第一个节假日。这个请求查询日本从 2026 年 11 月 9 日起的情况。

curl,日本的下一个节假日
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 是这类日子的稳定键。对单个国家来说,一次调用就能回答排期问题。对多个国家,可以逐个询问并保留最早的答案,或者像下一节那样读取整年的数据。

一次遍历找出各国的共同空闲日

  1. 获取 API 密钥 在注册页获取 API 密钥,并保存在 NARWHAL_API_KEY 中。
  2. 列出国家和时间窗口 脚本使用 USA、DEU、JPN 和 IDN,在 11 月 9 日到 30 日之间寻找连续 3 个空闲的工作日。3 天只是示例,请换成你的发布或维护窗口所需的长度,也请按你自己的团队修改国家列表和日期。
  3. 收集休息日的日期 每个国家一次请求就返回当年的节假日。脚本把每个 date 存入一个映射,键是日期,值是当天休息的国家集合。两个国家共有的日期会同时包含两个代码。
  4. 遍历工作日并输出报告 脚本先列出至少有一个国家休息的工作日,再找出第一段连续的空闲工作日。
    Python,休息日和第一段连续空闲日
    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 涵盖的范围

国家列表包含什么对排期的影响
USAfederal_government 范围退伍军人节和感恩节显示为休息
JPNnational_public 范围勤劳感谢日显示为休息
DEUnational_public 范围这个时间窗口内没有休息日
IDNnational_public 和 collective_leave这个时间窗口内没有休息日

依赖列表之前,先读每个响应中的 coverage。它写明了日历涵盖的 scope 和行政分区,而 scope 因国家而异。对于条目带有分区代码的国家,例如英国,还要多做一次检查:当条目的列表为空,或包含办公室所在的地区时,才保留该条目。

周末的节假日对排期有影响吗?

对遍历工作日的做法没有影响。脚本只看周一到周五,所以落在周六或周日的节假日会被跳过。有些国家会把假期顺延到工作日,并在新条目上标记 observed;该条目的日期是工作日,所以会显示为休息。

如果团队所在的国家有地区性节假日怎么办?

年度端点没有地区参数,所以要在你的代码里按 subdivision_codes 过滤。列表为空表示该节假日全国通用。在英国,每个银行假日对每组国家各出现一次,所以同一个日期可能有多个条目。

跨年的时间窗口需要多少次请求?

每个国家每一年一次请求。跨越 12 月 31 日的窗口,还需要每个国家下一年的列表;没有发布日历的年份会返回代码为 calendar_not_published 的 404。做长期排期时要预先处理这个响应,并把每一年的列表缓存起来,这样重复运行就不用再请求。

发布于。

后续步骤