DEV Community

Usman Khalil
Usman Khalil

Posted on • Edited on

51 3 1 1 3

Get Public Holidays By Country Using Google Calendar API

This is something that I picked up while working on a client's project. I was tasked with displaying holidays with respect to user's region. One thing led to another and here I'm writing a small tutorial post here.

Background

It's not that it's super hard. But the major problem I faced was lack of connecting pieces. Everything felt scattered around and I found it cumbersome to join things together. I thought moment.js might offer any such functionality but to no luck. I did find a sister package named moment-holiday but I felt like it's not completed as I couldn't find my country in it. A similar package date-holidays is also there and it has good API but yeah - it wasn't completed either.

I finally resorted to Google Calendar API thanks to this stackoverflow answer.

Google Calendar API

To use Google Calendar API, you need to have API key from Google. Go to Google Developer Console and from the credential section, create a API for yourself. Each request to calendar API would need that key to process successfully.

Fetching Holidays

Google Calendar documentation provides a good start to help you understand the basic idea. We'll be making a fetch request using this endpoint

GET https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events
Enter fullscreen mode Exit fullscreen mode

calendarId is the pain point here. A normal search won't give you a clear idea where exactly would one find this id. Stackoverflow queries end up getting few calendar ids but for rest of them, it took me few hours to get on. Thankfully, we have developers who open source their works to help other. I was expecting Google to have their list available in documentation but unfortunately that wasn't the case.

Anyhow, let's start with some JavaScript and do some grinding.

const BASE_CALENDAR_URL = "https://www.googleapis.com/calendar/v3/calendars";
const BASE_CALENDAR_ID_FOR_PUBLIC_HOLIDAY =
  "holiday@group.v.calendar.google.com"; // Calendar Id. This is public but apparently not documented anywhere officialy.
const API_KEY = "YOUR_API_KEY";
const CALENDAR_REGION = "en.usa"; // This variable refers to region whose holidays do we need to fetch
Enter fullscreen mode Exit fullscreen mode

There are other parameters available as well. Complete list can be found in the documentation here. Let's make a fetch request now.

/**
 * Making a fetch request
 */
const url = `${BASE_CALENDAR_URL}/${CALENDAR_REGION}%23${BASE_CALENDAR_ID_FOR_PUBLIC_HOLIDAY}/events?key=${API_KEY}`

fetch(url).then(response => response.json()).then(data => {
const holidays = data.items;
})

// A typical holidays would have this JSON structure:
{
  "kind": "calendar#event",
  "etag": "\"3262600847118000\"",
  "id": "20220417_3s7sr1qa2d9o9oe5cbgd3b6ju0",
  "status": "confirmed",
  "htmlLink": "https://www.google.com/calendar/event?eid=MjAyMjA0MTdfM3M3c3IxcWEyZDlvOW9lNWNiZ2QzYjZqdTAgZW4udXNhI2hvbGlkYXlAdg",
  "created": "2021-09-10T19:00:23.000Z",
  "updated": "2021-09-10T19:00:23.559Z",
  "summary": "Easter Sunday",
  "description": "Observance\nTo hide observances, go to Google Calendar Settings > Holidays in United States",
  "creator": {
    "email": "en.usa#holiday@group.v.calendar.google.com",
    "displayName": "Holidays in United States",
    "self": true
  },
  "organizer": {
    "email": "en.usa#holiday@group.v.calendar.google.com",
    "displayName": "Holidays in United States",
    "self": true
  },
  "start": {
    "date": "2022-04-17"
  },
  "end": {
    "date": "2022-04-18"
  },
  "transparency": "transparent",
  "visibility": "public",
  "iCalUID": "20220417_3s7sr1qa2d9o9oe5cbgd3b6ju0@google.com",
  "sequence": 0,
  "eventType": "default"
}
Enter fullscreen mode Exit fullscreen mode

In my case, I was mostly concerned with summary, start and end properties.

Fetching for Other Regions

My requirement included displaying holidays based on regions. For this purpose, I need list of all supported regions by Google Calendar. Luckily, someone on GitHub already did the hardwork on this part. Shoutout to mattn. You can find the list in this gist:

Australian Holidays,en.australian#holiday@group.v.calendar.google.com
Austrian Holidays,en.austrian#holiday@group.v.calendar.google.com
Brazilian Holidays,en.brazilian#holiday@group.v.calendar.google.com
Canadian Holidays,en.canadian#holiday@group.v.calendar.google.com
China Holidays,en.china#holiday@group.v.calendar.google.com
Christian Holidays,en.christian#holiday@group.v.calendar.google.com
Danish Holidays,en.danish#holiday@group.v.calendar.google.com
Dutch Holidays,en.dutch#holiday@group.v.calendar.google.com
Finnish Holidays,en.finnish#holiday@group.v.calendar.google.com
French Holidays,en.french#holiday@group.v.calendar.google.com
German Holidays,en.german#holiday@group.v.calendar.google.com
Greek Holidays,en.greek#holiday@group.v.calendar.google.com
Hong Kong (C) Holidays,en.hong_kong_c#holiday@group.v.calendar.google.com
Hong Kong Holidays,en.hong_kong#holiday@group.v.calendar.google.com
Indian Holidays,en.indian#holiday@group.v.calendar.google.com
Indonesian Holidays,en.indonesian#holiday@group.v.calendar.google.com
Iranian Holidays,en.iranian#holiday@group.v.calendar.google.com
Irish Holidays,en.irish#holiday@group.v.calendar.google.com
Islamic Holidays,en.islamic#holiday@group.v.calendar.google.com
Italian Holidays,en.italian#holiday@group.v.calendar.google.com
Japanese Holidays,en.japanese#holiday@group.v.calendar.google.com
Jewish Holidays,en.jewish#holiday@group.v.calendar.google.com
Malaysian Holidays,en.malaysia#holiday@group.v.calendar.google.com
Mexican Holidays,en.mexican#holiday@group.v.calendar.google.com
New Zealand Holidays,en.new_zealand#holiday@group.v.calendar.google.com
Norwegian Holidays,en.norwegian#holiday@group.v.calendar.google.com
Philippines Holidays,en.philippines#holiday@group.v.calendar.google.com
Polish Holidays,en.polish#holiday@group.v.calendar.google.com
Portuguese Holidays,en.portuguese#holiday@group.v.calendar.google.com
Russian Holidays,en.russian#holiday@group.v.calendar.google.com
Singapore Holidays,en.singapore#holiday@group.v.calendar.google.com
South Africa Holidays,en.sa#holiday@group.v.calendar.google.com
South Korean Holidays,en.south_korea#holiday@group.v.calendar.google.com
Spain Holidays,en.spain#holiday@group.v.calendar.google.com
Swedish Holidays,en.swedish#holiday@group.v.calendar.google.com
Taiwan Holidays,en.taiwan#holiday@group.v.calendar.google.com
Thai Holidays,en.thai#holiday@group.v.calendar.google.com
UK Holidays,en.uk#holiday@group.v.calendar.google.com
US Holidays,en.usa#holiday@group.v.calendar.google.com
Vietnamese Holidays,en.vietnamese#holiday@group.v.calendar.google.com
アイルランドの祝日,ja.irish#holiday@group.v.calendar.google.com
アメリカの祝日,ja.usa#holiday@group.v.calendar.google.com
イギリスの祝日,ja.uk#holiday@group.v.calendar.google.com
イスラム教の祝日,ja.islamic#holiday@group.v.calendar.google.com
イタリアの祝日,ja.italian#holiday@group.v.calendar.google.com
インドの祝日,ja.indian#holiday@group.v.calendar.google.com
インドネシアの祝日,ja.indonesian#holiday@group.v.calendar.google.com
オランダの祝日,ja.dutch#holiday@group.v.calendar.google.com
オーストラリアの祝日,ja.australian#holiday@group.v.calendar.google.com
オーストリアの祝日,ja.austrian#holiday@group.v.calendar.google.com
カナダの祝日,ja.canadian#holiday@group.v.calendar.google.com
キリスト教の祝日,ja.christian#holiday@group.v.calendar.google.com
ギリシャの祝日,ja.greek#holiday@group.v.calendar.google.com
シンガポールの祝日,ja.singapore#holiday@group.v.calendar.google.com
スウェーデンの祝日,ja.swedish#holiday@group.v.calendar.google.com
スペインの祝日,ja.spain#holiday@group.v.calendar.google.com
タイの祝日,ja.thai#holiday@group.v.calendar.google.com
デンマークの祝日,ja.danish#holiday@group.v.calendar.google.com
ドイツの祝日,ja.german#holiday@group.v.calendar.google.com
ニュージーランドの祝日,ja.new_zealand#holiday@group.v.calendar.google.com
ノルウェイの祝日,ja.norwegian#holiday@group.v.calendar.google.com
フィリピンの祝日,ja.philippines#holiday@group.v.calendar.google.com
フィンランドの祝日,ja.finnish#holiday@group.v.calendar.google.com
フランスの祝日,ja.french#holiday@group.v.calendar.google.com
ブラジルの祝日,ja.brazilian#holiday@group.v.calendar.google.com
ベトナムの祝日,ja.vietnamese#holiday@group.v.calendar.google.com
ポルトガルの祝日,ja.portuguese#holiday@group.v.calendar.google.com
ポーランドの祝日,ja.polish#holiday@group.v.calendar.google.com
マレーシアの祝日,ja.malaysia#holiday@group.v.calendar.google.com
メキシコの祝日,ja.mexican#holiday@group.v.calendar.google.com
ユダヤ教の祝日,ja.jewish#holiday@group.v.calendar.google.com
ロシアの祝日,ja.russian#holiday@group.v.calendar.google.com
中国の祝日,ja.china#holiday@group.v.calendar.google.com
韓国の祝日,ja.south_korea#holiday@group.v.calendar.google.com
南アフリカの祝日,ja.sa#holiday@group.v.calendar.google.com
台湾の祝日,ja.taiwan#holiday@group.v.calendar.google.com
日本の祝日,ja.japanese#holiday@group.v.calendar.google.com
香港(C)の祝日,ja.hong_kong_c#holiday@group.v.calendar.google.com
香港の祝日,ja.hong_kong#holiday@group.v.calendar.google.com



Hopefully this would help save someone's few hours.

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (10)

Collapse
 
vikashrathee profile image
Vikash Rathee

I ran it via node-fetch to fetch holidays, but the list is incomplete. Google doesn't return all holidays. So, I built this holidays API my personal use as well for other developers.

Install from NPM -

npm i 11holidays
Enter fullscreen mode Exit fullscreen mode

Get holidays

const holidays = await instance.holidays.list({country: 'US', year: '2023'});

Enter fullscreen mode Exit fullscreen mode

See GitHub - github.com/dayschedule/11holidays

Collapse
 
mynameistakenomg profile image
Sean_Fang

Thank you for sharing this tutorial 👍 I'm working on a project that allows users to make appointments, and in my case, showing holidays is very important as users will understand which days are available or not

Collapse
 
chinilaw profile image
Chinilaw TV

You're a life saver! Even gemini couldn't give me this answer!

I was getting error at first about authentication and then i realized i just missed copying the exact same wordings from the regions. Don't use #, instead the %23

Collapse
 
monfernape profile image
Usman Khalil

Glad that it was helpful.

Collapse
 
shaerif profile image
Sharif

Is this works if you want to get the holidays list to google sheets as well?

Collapse
 
ksi9302 profile image
Peter Sugin Kim

Bless your soul sir, you saved me not hours but days + having to subscribe to those expensive holiday apis.

Collapse
 
monfernape profile image
Usman Khalil

I'm glad I was helpful.

Collapse
 
sashaajin profile image
Sasha Ajintarev

every single event has description property. Sometimes it is equal to : "Observance\nTo hide observances, go to Google Calendar Settings \u003e Holidays in Bulgaria" . Do smd can help to hide it

Collapse
 
dhamu143 profile image
Dharmesh

can you provide more in details with screenshot of how we can generate that API key from google console. ?

Collapse
 
iprastha profile image
Indra Prastha

Once you are signed in to Google Cloud console , you can access API credential manager from: console.cloud.google.com/apis/cred...
From there click on create credentials and get your API key.
Don't forget to enable the Calendar API library first by going to: console.cloud.google.com/apis/libr... , and click on Enable

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up