mirror of
https://github.com/Luzifer/go-holidays.git
synced 2024-12-25 05:11:17 +00:00
Add US federal holidays
This commit is contained in:
parent
25523a5078
commit
025b87d81e
2 changed files with 116 additions and 0 deletions
45
holidays_us.go
Normal file
45
holidays_us.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package holidays
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registerHolidayDataSource("us", holidaysUSNational{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type holidaysUSNational struct{}
|
||||||
|
|
||||||
|
func (h holidaysUSNational) GetIncludes() []string { return []string{} }
|
||||||
|
func (h holidaysUSNational) GetHolidays(year int) []Holiday {
|
||||||
|
return []Holiday{
|
||||||
|
newHoliday("New Year's Day", map[string]string{}, h.fixWeekend(dateFromNumbers(year, 1, 1))), // 1st January
|
||||||
|
newHoliday("Birthday of Martin Luther King, Jr.", map[string]string{}, h.findNextWeekday(dateFromNumbers(year, 1, 15), time.Monday)), // Third Monday in January
|
||||||
|
newHoliday("Washington's Birthday", map[string]string{}, h.findNextWeekday(dateFromNumbers(year, 2, 15), time.Monday)), // Third Monday in February
|
||||||
|
newHoliday("Memorial Day", map[string]string{}, h.findNextWeekday(dateFromNumbers(year, 5, 25), time.Monday)), // Last Monday in May
|
||||||
|
newHoliday("Independence Day", map[string]string{}, h.fixWeekend(dateFromNumbers(year, 7, 4))), // 4 July
|
||||||
|
newHoliday("Labor Day", map[string]string{}, h.findNextWeekday(dateFromNumbers(year, 9, 1), time.Monday)), // First Monday in September
|
||||||
|
newHoliday("Columbus Day", map[string]string{}, h.findNextWeekday(dateFromNumbers(year, 10, 8), time.Monday)), // Second Monday in October
|
||||||
|
newHoliday("Veterans Day", map[string]string{}, h.fixWeekend(dateFromNumbers(year, 11, 11))), // 11 November
|
||||||
|
newHoliday("Thanksgiving Day", map[string]string{}, h.findNextWeekday(dateFromNumbers(year, 11, 23), time.Thursday)), // Fourth Thursday in November
|
||||||
|
newHoliday("Christmas Day", map[string]string{}, h.fixWeekend(dateFromNumbers(year, 12, 25))), // 25 December
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h holidaysUSNational) findNextWeekday(in time.Time, wd time.Weekday) time.Time {
|
||||||
|
for in.Weekday() != wd {
|
||||||
|
in = in.Add(1 * 24 * time.Hour)
|
||||||
|
}
|
||||||
|
return in
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a holiday falls on a Saturday it is celebrated the preceding Friday;
|
||||||
|
// if a holiday falls on a Sunday it is celebrated the following Monday.
|
||||||
|
func (h holidaysUSNational) fixWeekend(in time.Time) time.Time {
|
||||||
|
switch in.Weekday() {
|
||||||
|
case time.Saturday:
|
||||||
|
return in.Add(-1 * 24 * time.Hour)
|
||||||
|
case time.Sunday:
|
||||||
|
return in.Add(1 * 24 * time.Hour)
|
||||||
|
default:
|
||||||
|
return in
|
||||||
|
}
|
||||||
|
}
|
71
holidays_us_test.go
Normal file
71
holidays_us_test.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package holidays
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHolidaysUS(t *testing.T) {
|
||||||
|
// List of known dates according to US Office of Personnel Management
|
||||||
|
// https://www.opm.gov/policy-data-oversight/snow-dismissal-procedures/federal-holidays/
|
||||||
|
|
||||||
|
knownDates := map[int]map[string]time.Time{
|
||||||
|
2011: map[string]time.Time{
|
||||||
|
"New Year's Day": dateFromNumbers(2010, 12, 31), // 1 = Saturday... What the hell are you doing?!?
|
||||||
|
"Birthday of Martin Luther King, Jr.": dateFromNumbers(2011, 1, 17),
|
||||||
|
"Washington's Birthday": dateFromNumbers(2011, 2, 21),
|
||||||
|
"Memorial Day": dateFromNumbers(2011, 5, 30),
|
||||||
|
"Independence Day": dateFromNumbers(2011, 7, 4),
|
||||||
|
"Labor Day": dateFromNumbers(2011, 9, 5),
|
||||||
|
"Columbus Day": dateFromNumbers(2011, 10, 10),
|
||||||
|
"Veterans Day": dateFromNumbers(2011, 11, 11),
|
||||||
|
"Thanksgiving Day": dateFromNumbers(2011, 11, 24),
|
||||||
|
"Christmas Day": dateFromNumbers(2011, 12, 26), // 25 = Sunday
|
||||||
|
},
|
||||||
|
2014: map[string]time.Time{
|
||||||
|
"New Year's Day": dateFromNumbers(2014, 1, 1),
|
||||||
|
"Birthday of Martin Luther King, Jr.": dateFromNumbers(2014, 1, 20),
|
||||||
|
"Washington's Birthday": dateFromNumbers(2014, 2, 17),
|
||||||
|
"Memorial Day": dateFromNumbers(2014, 5, 26),
|
||||||
|
"Independence Day": dateFromNumbers(2014, 7, 4),
|
||||||
|
"Labor Day": dateFromNumbers(2014, 9, 1),
|
||||||
|
"Columbus Day": dateFromNumbers(2014, 10, 13),
|
||||||
|
"Veterans Day": dateFromNumbers(2014, 11, 11),
|
||||||
|
"Thanksgiving Day": dateFromNumbers(2014, 11, 27),
|
||||||
|
"Christmas Day": dateFromNumbers(2014, 12, 25),
|
||||||
|
},
|
||||||
|
2017: map[string]time.Time{
|
||||||
|
"New Year's Day": dateFromNumbers(2017, 1, 2), // 1 = Sunday
|
||||||
|
"Birthday of Martin Luther King, Jr.": dateFromNumbers(2017, 1, 16),
|
||||||
|
"Washington's Birthday": dateFromNumbers(2017, 2, 20),
|
||||||
|
"Memorial Day": dateFromNumbers(2017, 5, 29),
|
||||||
|
"Independence Day": dateFromNumbers(2017, 7, 4),
|
||||||
|
"Labor Day": dateFromNumbers(2017, 9, 4),
|
||||||
|
"Columbus Day": dateFromNumbers(2017, 10, 9),
|
||||||
|
"Veterans Day": dateFromNumbers(2017, 11, 10), // 11 = Saturday
|
||||||
|
"Thanksgiving Day": dateFromNumbers(2017, 11, 23),
|
||||||
|
"Christmas Day": dateFromNumbers(2017, 12, 25),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for year, knownHolidays := range knownDates {
|
||||||
|
generatedHolidays, err := GetHolidays("us", year)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("[US] Could not load holidays for %d: %s", year, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, date := range knownHolidays {
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, hd := range generatedHolidays {
|
||||||
|
if hd.Name == name && hd.ParsedDate == date {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Errorf("[US] Did not find %q on %s.", name, date.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue