A pure Go library for determining public holidays across different countries and their subdivisions (states, provinces, regions). Provides accurate holiday calculations including movable dates (Easter-based, lunar calendar, astronomical events) and country-specific rules.
- Production-Ready: Thread-safe caching, binary search optimization, zero allocations for lookups, automatic lazy loading
- Subdivision Handling: Support for state, province, and region-specific holidays
- Movable Holidays: Accurate calculation of Easter-based Catholic holidays, Chinese lunar festivals, Japanese equinoxes
- Historical Accuracy: Year-specific rules for holidays that change dates or names over time
- Zero Dependencies: Pure Go implementation with no external dependencies
- High Performance: O(log n) holiday lookups, automatic result caching, concurrent-safe with no data races
- Automatic Loading: Country providers load on-demand on first use
- Calendar Utilities: Helper functions for finding specific days (first Monday, last Friday, etc.)
This library was specifically built to power the Time APIs at Requiems, a production-ready API platform serving developers worldwide.
Most Popular Time APIs:
- Holiday Checking - Instant holiday validation for any country
- Working Day Calculations - Business days between dates with holiday awareness
- Holiday Listings - Complete holiday calendars for any year or range
- Timezone Operations - Convert and manage times across global zones
- Date Math - Add/subtract business days respecting holidays
...and many more time utilities. Browse all Time APIs β
Why Requiems? Skip the infrastructure headache. Get this battle-tested holiday data through a simple REST API with global CDN, authentication, rate limiting, and 99.9% uptime, or use this Go library directly for zero-dependency integration.
go get github.com/bobadilla-tech/holidays-per-countryCheck if a specific date is a holiday:
package main
import (
"fmt"
"time"
"github.com/bobadilla-tech/holidays-per-country"
)
func main() {
date := time.Date(2024, 12, 25, 0, 0, 0, 0, time.UTC)
if holidays.IsHoliday(date, "US") {
fmt.Println("December 25, 2024 is a holiday in the United States")
}
}Retrieve all holidays for a specific country and year:
package main
import (
"fmt"
"github.com/bobadilla-tech/holidays-per-country"
)
func main() {
// Canada holidays for 2024
holidays := holidays.GetHolidays("CA", 2024)
for _, holiday := range holidays {
fmt.Printf("%s: %s\n", holiday.Date.Format("2006-01-02"), holiday.Name)
}
}Find all holidays within a specific date range:
package main
import (
"fmt"
"time"
"github.com/bobadilla-tech/holidays-per-country"
)
func main() {
start := time.Date(2024, 6, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2024, 8, 31, 0, 0, 0, 0, time.UTC)
holidays := holidays.GetHolidaysInRange("US", start, end)
fmt.Printf("Summer holidays in the US (2024):\n")
for _, holiday := range holidays {
fmt.Printf("%s: %s\n", holiday.Date.Format("2006-01-02"), holiday.Name)
}
}Filter holidays by subdivision (state, province, region):
package main
import (
"fmt"
"github.com/bobadilla-tech/holidays-per-country"
)
func main() {
holidays := holidays.GetHolidays("AU", 2024)
// Filter holidays for Victoria
for _, holiday := range holidays {
// Check if holiday applies to Victoria
if len(holiday.Subdivisions) == 0 || contains(holiday.Subdivisions, "AU-VIC") {
fmt.Printf("%s: %s\n", holiday.Date.Format("2006-01-02"), holiday.Name)
}
}
}
func contains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
}Represents a public holiday:
type Holiday struct {
Date time.Time // The date of the holiday
Name string // The holiday name
Subdivisions []string // Subdivision codes where the holiday applies (empty = nationwide)
Fixed bool // Whether the holiday falls on a fixed date each year
}Checks if a specific date is a public holiday in the given country.
- Parameters:
date: The date to checkcountryCode: ISO 3166-1 alpha-2 country code (e.g., "US", "CA", "GB")
- Returns:
trueif the date is a holiday,falseotherwise
Returns all public holidays for a specific country and year.
- Parameters:
countryCode: ISO 3166-1 alpha-2 country codeyear: The year to query
- Returns: Slice of
Holidayobjects
Returns all holidays within a date range for a specific country.
- Parameters:
countryCode: ISO 3166-1 alpha-2 country codestartDate: Start of the date range (inclusive)endDate: End of the date range (inclusive)
- Returns: Slice of
Holidayobjects in chronological order
Many providers support subdivision-specific holidays using ISO 3166-2 codes:
- Australia: AU-ACT, AU-NSW, AU-NT, AU-QLD, AU-SA, AU-TAS, AU-VIC, AU-WA
- Canada: CA-AB, CA-BC, CA-MB, CA-NB, CA-NL, CA-NT, CA-NS, CA-NU, CA-ON, CA-PE, CA-QC, CA-SK, CA-YT
- Germany: DE-BB, DE-BE, DE-BW, DE-BY, DE-HB, DE-HE, DE-HH, DE-MV, DE-NI, DE-NW, DE-RP, DE-SH, DE-SL, DE-SN, DE-ST, DE-TH
- Spain: ES-AN, ES-AR, ES-AS, ES-CB, ES-CE, ES-CL, ES-CM, ES-CN, ES-CT, ES-EX, ES-GA, ES-IB, ES-MC, ES-MD, ES-ML, ES-NC, ES-PV, ES-RI, ES-VC
- United Kingdom: GB-ENG, GB-NIR, GB-SCT, GB-WLS
- United States: US-CT, US-DE, US-FL, US-HI, US-IL, US-IN, US-KY, US-LA, US-MO, US-MT, US-NC, US-NJ, US-TN, and more
Each country is implemented as a provider that registers holidays for a given year:
type Provider interface {
RegisterHolidays(year int) []Holiday
}The library handles different types of holidays:
- Fixed Holidays: Same date every year (e.g., New Year's Day on January 1)
- Movable Holidays:
- Catholic Easter-based: Good Friday, Easter Monday, Ascension Day, Pentecost, Corpus Christi, etc.
- Lunar Calendar: Chinese Spring Festival, Dragon Boat Festival, Mid-Autumn Festival
- Astronomical: Japanese vernal and autumnal equinoxes
- Rule-Based: Holidays that shift based on:
- Day of week (e.g., first Monday in September)
- Conditional logic (e.g., presidential inauguration years)
- Historical changes (e.g., holiday name changes, new holidays added)
The library provides date calculation utilities in the
github.com/bobadilla-tech/holidays-per-country/providers/calc package:
Date Finding Functions:
FindDay(year, month, dayOfWeek, occurrence): Find the Nth occurrence of a weekday (e.g., 3rd Monday of February)FindLastDay(year, month, dayOfWeek): Find the last occurrence of a weekday in a monthFindNextDay(date, dayOfWeek): Find the next occurrence of a specific weekdayFindDayBefore(date, dayOfWeek): Find the previous occurrence of a specific weekdayFindDayBetween(startDate, endDate, dayOfWeek): Find a specific weekday within a date range
Catholic Calendar Functions:
CatholicEasterSunday(year): Calculate Easter Sunday using Gauss's algorithmCatholicGoodFriday(year): Calculate Good FridayCatholicEasterMonday(year): Calculate Easter MondayCatholicAscensionDay(year): Calculate Ascension Day (39 days after Easter)CatholicPentecost(year): Calculate Pentecost Sunday (49 days after Easter)CatholicWhitMonday(year): Calculate Whit MondayCatholicCorpusChristi(year): Calculate Corpus Christi
Chinese Lunisolar Calendar:
ChineseLunisolarToGregorian(year, month, day): Convert Chinese lunar dates to Gregorian dates (supports years 1900-2100)
Example Usage:
import "github.com/bobadilla-tech/holidays-per-country/providers/calc"
// Find the 3rd Monday in January 2024 (Martin Luther King Jr. Day)
mlkDay := calc.FindDay(2024, time.January, time.Monday, 3)
// Calculate Easter Sunday for 2024
easter := calc.CatholicEasterSunday(2024)
// Convert Chinese New Year 2024 (lunar year 2024, month 1, day 1)
chineseNewYear, ok := calc.ChineseLunisolarToGregorian(2024, 1, 1)Run the test suite:
go test ./...Run tests with coverage:
go test -cover ./...Run tests with race detector (verifies thread-safety):
go test -race ./...Run tests for a specific provider:
go test ./providers -run TestUnitedStatesProviderContributions are welcome! Please see CONTRIBUTING.md for detailed guidelines on:
- Adding new country providers
- Reporting bugs and requesting features
- Code style and testing requirements
- Pull request process
Quick start for adding a country:
- Create a new file in
providers/named{countrycode}.go - Implement the provider following the pattern in existing providers
- Use helper functions from
providers/calc/for date calculations (Easter, lunar calendar, date finding utilities) - Add tests in
providers/{countrycode}_test.go - Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
Holiday data and rules derived from: