List public holidays for several countries

In 2026 the United States has 11 public holidays, the United Kingdom 14, Japan 18, Germany 9 and Indonesia 17, and only 1 January falls on the same date in all five. Loop over country codes with one request per country and year, then collect the countries under each holiday date to compare their calendars.

Do it with the API

  1. Get a key and set the environment variable Get a free key at signup and keep it in an environment variable called NARWHAL_API_KEY. The script reads that variable and sends the key as Authorization: Bearer YOUR_KEY, so use the environment where you will run Python.
  2. Choose the countries and year Use ISO 3166 alpha-3 country codes with GET /v1/calendars/holidays/{country}/{year}: the example requests USA, GBR, JPN, DEU and IDN for 2026. Each country and year needs its own request, so this comparison makes five requests; keep the year the same across the countries you want to compare.
  3. Collect the countries under each date Run the Python script to request each country's holidays and group the response entries by date, with a set of country codes for each date. The script sorts those dates, prints those shared by at least three countries, then counts the distinct dates for each country across the complete collection, including dates that do not appear in the shared-date output.
    Python, holidays for five countries
    import os
    from collections import defaultdict
    import requests
    
    HEADERS = {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"}
    COUNTRIES = ["USA", "GBR", "JPN", "DEU", "IDN"]
    
    by_date = defaultdict(set)
    for country in COUNTRIES:
        r = requests.get(f"https://api.narwhalapi.com/v1/calendars/holidays/{country}/2026",
                         params={"scope": "national_public"} if country == "IDN" else None,
                         headers=HEADERS, timeout=10)
        r.raise_for_status()
        for h in r.json()["holidays"]:
            by_date[h["date"]].add(country)
    
    for day in sorted(by_date):
        if len(by_date[day]) >= 3:
            print(day, sorted(by_date[day]))
    print({c: sum(1 for d in by_date.values() if c in d) for c in COUNTRIES})
  4. Read the shared dates and country totals For 2026, the shared-date output contains 1 January, 3 April, 25 May and 25 December, and the final line contains each country's distinct-date total. Those totals use the United States' federal_government scope, the United Kingdom's bank scope and Japan's and Germany's national_public scope; the Indonesia request explicitly selects national_public.

Read a shared date's country list separately from its holiday name. On 25 May 2026, Germany, the United Kingdom and the United States share a holiday date; in the United States it is Memorial Day. The script groups dates, so a match does not require the countries to use the same holiday name. On 3 April 2026, Good Friday appears for Germany, the United Kingdom and Indonesia, so that date also meets the shared-date threshold. Its country list contains DEU, GBR and IDN.

Do it in a sheet or without code

Open each country's holiday calendar page to compare the dates without a script. For a spreadsheet comparison, paste each country's dates into its own column and keep a single entry for each distinct date within that country. Put the date you want to compare in A2, with the other countries' date lists in columns B:E.

Count matching dates in the other columns
=COUNTIF(B:E, A2)

The formula counts matching cells in the other countries' columns. The country whose list is in column A is already represented by the date in A2, so read the formula result as matches elsewhere in the sheet. Keep each country's dates together when you paste them, so you can trace a match back to its calendar. Copy the formula alongside the dates you want to compare in column A. Read each result against the date on that row; the formula searches the other columns for the same date, so their lists do not need matching row positions.

Which option to use when

SituationBest optionWhy
Compare two or three countries onceCalendar pagesRead each country's holiday dates directly
Build a team calendar or handle payroll across officesThe script, run once a year per countryCollect countries under each date and count distinct dates
Include only some regionsFilter by subdivision_codes in the responseSelect the subdivisions relevant to the comparison

Why are the United Kingdom's rows doubled?

Bank holidays differ by nation, so each date appears once per group of subdivisions. In 2026, the United Kingdom response has 28 raw rows because England and Wales, Northern Ireland and Scotland have separate rows, while the combined calendar has 14 distinct dates. Collect dates in a set when you want the country's distinct-date total.

For a regional calendar, use subdivision_codes in the response to select the relevant entries before collecting dates. That keeps the region selection separate from the distinct-date count.

How do I leave out collective leave days?

Pass scope=national_public for Indonesia to leave out collective leave days, called cuti bersama. For 2026, that selection has 17 distinct public holiday dates, while the unfiltered response has 25 rows because it also includes collective_leave entries. The scope parameter belongs on the Indonesia request in this comparison.

Apply the scope before adding dates to the combined collection. Otherwise, the Indonesia entries include collective leave when you compare shared dates or count the country's holidays.

Do countries count weekend holidays the same way?

No, each country's list uses the date that country sets. Some countries move a holiday to a weekday and mark it observed. Use the response's date for the comparison, including an observed date where it appears, rather than moving every weekend holiday according to a single rule across the countries.

Worked example: 25 December 2026

Start with 25 December 2026 and look for that date in each country's selected holiday list. Germany, the United Kingdom, Indonesia and the United States each contribute a country code; Japan does not have a holiday on that date. Treat each matching country as a single contribution, even when its response contains separate regional rows for that date.

CountryCodeHoliday on 25 December 2026
GermanyDEUYes
United KingdomGBRYes
IndonesiaIDNYes
United StatesUSAYes
JapanJPNNo
TotalDEU, GBR, IDN, USA4 of 5 countries

Count the distinct country codes for 25 December 2026 to get four of the five countries. The date qualifies for the script's output because it is shared by at least three. For comparison, 1 January 2026 has all five country codes and is the only date shared by all five during 2026.

Published .