LoginSignup
1
0

More than 3 years have passed since last update.

Get observed public holidays list from Google API

Posted at

There is a useful Google API available to developers who register with the Google Console and obtain an API key. For a chosen country, this API returns a list of dates which are public holidays.

However, there are problems with the default output, e.g

  • a single public holiday may in some cases have an original date and an observed (if, for example, the original date is not possible e.g. is on a weekend). The API returns both dates as separate items.
  • multiple holidays can are given with different dates but identical names
  • a single public holiday date can be duplicated, with some instances including an extra "holiday" suffix in their name
  • holidays with identical names but from multiple years (both previous, current and future years) are given

The method for extracting a list of OBSERVED public holidays in Japan, in Japanese language is presented here for iOS/Swift

URL

https://www.googleapis.com/calendar/v3/calendars/{LANGUAGE}.{COUNTRY}%23holiday%40group.v.calendar.google.com/events?key={API_KEY}

where

  • {LANGUAGE} is the requested language, e.g: ja, en
  • {COUNTRY} is the requested country, e.g: japanese, uk, french
  • {API_KEY} is the API key from your developer account

Define a custom date handler object

This object helps to compare dates extracted from the API

struct PublicHoliday{

    // some holiday names are provided with an "observed" suffix - so we define a base name (without this suffix) to more easily compare dates 
    let baseName: String
    let name: String
    let start: String
    let end: String

    let observedKeyword: String = "observed"

    // let dates with the "observed" keyword take priority (override) for a specific holiday date
    var isOverride: Bool {
        get {
            return self.name.contains(observedKeyword)
        }
    }


    init(name: String, start: String, end: String) {
        self.name = name
        self.start = start
        self.end = end

        let components = name.split(separator: " ")
        if let last = components.last, last == observedKeyword {
            self.baseName = components.dropLast().joined(separator: " ")
        }
        else {
            self.baseName = name
        }
    }

    init(date: String) {
        self.init(name: "", start: date, end: date)
    }
}

Parse Response in Swift

The following parse function extracts only observed public holidays for the current as an array of Public Holiday objects

class GoogleCalendarAPIParser {


    static func process(json: [String: Any]) -> [PublicHoliday] {

        guard let items = json["items"] as? JSONArray,
            0 < items.count else {
            return []
        }

        // extract all dates
        var dates: [PublicHoliday] = items.compactMap { item in

            guard
                let name= item["summary"] as? String,
                let start = item["start"] as? [String: Any],
                let end = item["start"] as? [String: Any],
                let startDate = start["date"] as? String,
                let endDate = end["date"] as? String
            else {
                Swift.print("unable to parse dates", item)
                return nil
            }

            return PublicHoliday(
                name: name,
                start: startDate,
                end: endDate
            )
        }


        // keep only dates from the current year
        let currentYear = String(Calendar.current.component(.year, from: Date()))
        dates = dates.filter { $0.startDate.split("-")[0] == currentYear }

        // keep dates that are overrides (the "observed" date) and dates which are not overriden by other dates
        dates = dates.filter { date in
            let isOverride = date.isOverride
            let hasNoOverride = dates.filter {
                $0.baseName == date.baseName && $0.isOverride
                }.isEmpty
            return isOverride || hasNoOverride
        }
        return dates
    } 
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0