Skip to content

Commit

Permalink
feat: add kenyan holidays
Browse files Browse the repository at this point in the history
  • Loading branch information
st3v3nmw committed Dec 12, 2024
1 parent 8a7a3c4 commit 32b9252
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 0 deletions.
121 changes: 121 additions & 0 deletions v2/ke/ke_holidays.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// (c) Rick Arnold. Licensed under the BSD license (see LICENSE).

// Package ke provides holiday definitions for Kenya.
package ke

import (
"time"

"github.com/rickar/cal/v2"
"github.com/rickar/cal/v2/aa"
)

var (
// Standard KE weekend substitution rules:
// Sundays move to Monday
weekendAlt = []cal.AltDay{
{Day: time.Sunday, Offset: 1},
}

// NewYear represents New Year's Day on 1-Jan
NewYear = aa.NewYear.Clone(&cal.Holiday{
Name: "New Year's Day",
Type: cal.ObservancePublic,
Observed: weekendAlt,
})

// GoodFriday represents Good Friday - two days before Easter
GoodFriday = aa.GoodFriday.Clone(&cal.Holiday{Name: "Good Friday", Type: cal.ObservancePublic})

// EasterMonday represents Easter Monday - the day after Easter
EasterMonday = aa.EasterMonday.Clone(&cal.Holiday{Name: "Easter Monday", Type: cal.ObservancePublic})

// LabourDay represents Labour Day on 1-May
LabourDay = aa.WorkersDay.Clone(&cal.Holiday{
Name: "Labour Day",
Type: cal.ObservancePublic,
Observed: weekendAlt,
})

// MadarakaDay represents Madaraka/Self-Governance Day on 1-Jun
MadarakaDay = &cal.Holiday{
Name: "Madaraka Day",
Type: cal.ObservancePublic,
Month: time.June,
Day: 1,
Observed: weekendAlt,
Func: cal.CalcDayOfMonth,
}

// UtamaduniDay represents Utamaduni Day on 10-Oct
UtamaduniDay = &cal.Holiday{
Name: "Utamaduni Day",
Type: cal.ObservancePublic,
Month: time.October,
Day: 10,
Observed: weekendAlt,
Func: cal.CalcDayOfMonth,
StartYear: 2022,
EndYear: 2023,
}

// MazingiraDay represents Environment Conservation Day on 10-Oct
MazingiraDay = &cal.Holiday{
Name: "Mazingira Day",
Type: cal.ObservancePublic,
Month: time.October,
Day: 10,
Observed: weekendAlt,
Func: cal.CalcDayOfMonth,
StartYear: 2024,
}

// MashujaaDay represents Heroes' Day on 20-Oct
MashujaaDay = &cal.Holiday{
Name: "Mashujaa Day",
Type: cal.ObservancePublic,
Month: time.October,
Day: 20,
Observed: weekendAlt,
Func: cal.CalcDayOfMonth,
StartYear: 2010,
}

// JamhuriDay represents Heroes' Day on 12-Dec
JamhuriDay = &cal.Holiday{
Name: "Jamhuri Day",
Type: cal.ObservancePublic,
Month: time.December,
Day: 12,
Observed: weekendAlt,
Func: cal.CalcDayOfMonth,
}

// ChristmasDay represents Christmas Day on 25-Dec
ChristmasDay = aa.ChristmasDay.Clone(&cal.Holiday{
Name: "Christmas Day",
Type: cal.ObservancePublic,
Observed: weekendAlt,
})

// BoxingDay represents Boxing Day on 26-Dec
BoxingDay = aa.ChristmasDay2.Clone(&cal.Holiday{
Name: "Boxing Day",
Type: cal.ObservancePublic,
Observed: weekendAlt,
})

// Holidays provides a list of the standard national holidays
Holidays = []*cal.Holiday{
NewYear,
GoodFriday,
EasterMonday,
LabourDay,
MadarakaDay,
MazingiraDay,
MashujaaDay,
JamhuriDay,
ChristmasDay,
BoxingDay,
}
)
84 changes: 84 additions & 0 deletions v2/ke/ke_holidays_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// (c) Rick Arnold. Licensed under the BSD license (see LICENSE).

package ke

import (
"testing"
"time"

"github.com/rickar/cal/v2"
)

func d(y, m, d int) time.Time {
return time.Date(y, time.Month(m), d, 0, 0, 0, 0, cal.DefaultLoc)
}

func TestHolidays(t *testing.T) {
tests := []struct {
h *cal.Holiday
y int
wantAct time.Time
wantObs time.Time
}{
{NewYear, 2022, d(2022, 1, 1), d(2022, 1, 1)},
{NewYear, 2023, d(2023, 1, 1), d(2023, 1, 2)},
{NewYear, 2024, d(2024, 1, 1), d(2024, 1, 1)},
{NewYear, 2025, d(2025, 1, 1), d(2025, 1, 1)},

{GoodFriday, 2022, d(2022, 4, 15), d(2022, 4, 15)},
{GoodFriday, 2023, d(2023, 4, 7), d(2023, 4, 7)},
{GoodFriday, 2024, d(2024, 3, 29), d(2024, 3, 29)},
{GoodFriday, 2025, d(2025, 4, 18), d(2025, 4, 18)},

{EasterMonday, 2022, d(2022, 4, 18), d(2022, 4, 18)},
{EasterMonday, 2023, d(2023, 4, 10), d(2023, 4, 10)},
{EasterMonday, 2024, d(2024, 4, 1), d(2024, 4, 1)},
{EasterMonday, 2025, d(2025, 4, 21), d(2025, 4, 21)},

{LabourDay, 2022, d(2022, 5, 1), d(2022, 5, 2)},
{LabourDay, 2023, d(2023, 5, 1), d(2023, 5, 1)},
{LabourDay, 2024, d(2024, 5, 1), d(2024, 5, 1)},
{LabourDay, 2025, d(2025, 5, 1), d(2025, 5, 1)},

{MadarakaDay, 2022, d(2022, 6, 1), d(2022, 6, 1)},
{MadarakaDay, 2023, d(2023, 6, 1), d(2023, 6, 1)},
{MadarakaDay, 2024, d(2024, 6, 1), d(2024, 6, 1)},
{MadarakaDay, 2025, d(2025, 6, 1), d(2025, 6, 2)},

{UtamaduniDay, 2022, d(2022, 10, 10), d(2022, 10, 10)},
{UtamaduniDay, 2023, d(2023, 10, 10), d(2023, 10, 10)},

{MazingiraDay, 2024, d(2024, 10, 10), d(2024, 10, 10)},
{MazingiraDay, 2025, d(2025, 10, 10), d(2025, 10, 10)},

{MashujaaDay, 2022, d(2022, 10, 20), d(2022, 10, 20)},
{MashujaaDay, 2023, d(2023, 10, 20), d(2023, 10, 20)},
{MashujaaDay, 2024, d(2024, 10, 20), d(2024, 10, 21)},
{MashujaaDay, 2025, d(2025, 10, 20), d(2025, 10, 20)},

{JamhuriDay, 2022, d(2022, 12, 12), d(2022, 12, 12)},
{JamhuriDay, 2023, d(2023, 12, 12), d(2023, 12, 12)},
{JamhuriDay, 2024, d(2024, 12, 12), d(2024, 12, 12)},
{JamhuriDay, 2025, d(2025, 12, 12), d(2025, 12, 12)},

{ChristmasDay, 2022, d(2022, 12, 25), d(2022, 12, 26)},
{ChristmasDay, 2023, d(2023, 12, 25), d(2023, 12, 25)},
{ChristmasDay, 2024, d(2024, 12, 25), d(2024, 12, 25)},
{ChristmasDay, 2025, d(2025, 12, 25), d(2025, 12, 25)},

{BoxingDay, 2022, d(2022, 12, 26), d(2022, 12, 26)},
{BoxingDay, 2023, d(2023, 12, 26), d(2023, 12, 26)},
{BoxingDay, 2024, d(2024, 12, 26), d(2024, 12, 26)},
{BoxingDay, 2025, d(2025, 12, 26), d(2025, 12, 26)},
}

for _, test := range tests {
gotAct, gotObs := test.h.Calc(test.y)
if !gotAct.Equal(test.wantAct) {
t.Errorf("%s %d: got actual: %s, want: %s", test.h.Name, test.y, gotAct.String(), test.wantAct.String())
}
if !gotObs.Equal(test.wantObs) {
t.Errorf("%s %d: got observed: %s, want: %s", test.h.Name, test.y, gotObs.String(), test.wantObs.String())
}
}
}

0 comments on commit 32b9252

Please sign in to comment.