-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #114 from DanailPenev/DanailPenev/add-bulgarian-ho…
…lidays Add Bulgarian holidays
- Loading branch information
Showing
2 changed files
with
267 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package bg | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/rickar/cal/v2" | ||
"github.com/rickar/cal/v2/aa" | ||
) | ||
|
||
var ( | ||
// Standard BG weekend substitution rules: | ||
// Saturdays move to Monday | ||
// Sundays move to Monday | ||
weekendAlt = []cal.AltDay{ | ||
{Day: time.Saturday, Offset: 2}, | ||
{Day: time.Sunday, Offset: 1}, | ||
} | ||
// NewYear represents New Year's Day on 1-Jan | ||
NewYear = aa.NewYear.Clone(&cal.Holiday{Name: "Нова година", Type: cal.ObservancePublic, Observed: weekendAlt}) | ||
|
||
// LiberationDay represents Liberation Day on 3-Mar | ||
LiberationDay = &cal.Holiday{ | ||
Name: "Ден на Освобождението на България от османско иго - национален празник", | ||
Type: cal.ObservancePublic, | ||
Month: time.March, | ||
Day: 3, | ||
Func: cal.CalcDayOfMonth, | ||
Observed: weekendAlt, | ||
} | ||
|
||
// GoodFriday represents Good Friday - two days before Easter | ||
OrthodoxGoodFriday = &cal.Holiday{ | ||
Name: "Велики петък", | ||
Type: cal.ObservancePublic, | ||
Offset: -2, | ||
Julian: true, | ||
Func: cal.CalcEasterOffset, | ||
} | ||
|
||
// EasterMonday represents Easter Monday on the day after Easter | ||
OrthodoxEasterMonday = &cal.Holiday{ | ||
Name: "Великден", | ||
Type: cal.ObservancePublic, | ||
Offset: 1, | ||
Julian: true, | ||
Func: cal.CalcEasterOffset, | ||
} | ||
|
||
// LabourDay represents Labour Day on 1-May | ||
LabourDay = &cal.Holiday{ | ||
Name: "Ден на труда и на международната работническа солидарност", | ||
Type: cal.ObservancePublic, | ||
Month: time.May, | ||
Day: 1, | ||
Func: func(h *cal.Holiday, year int) time.Time { | ||
// May 1st is quite close to OrthodoxEaster so we need to make an extra check | ||
// If LabourDay falls on a Saturday or Sunday and Good Friday is on the Friday before that, | ||
// then LabourDay is observed on the Tuesday after Easter. | ||
easter := cal.CalcEasterOffset(OrthodoxGoodFriday, year) | ||
labourDay := cal.CalcDayOfMonth(h, year) | ||
daysDiff := labourDay.Sub(easter).Hours() / 24 | ||
if daysDiff <= 2 { | ||
holiday := *h | ||
holiday.Offset = 2 | ||
holiday.Julian = true | ||
return cal.CalcEasterOffset(&holiday, year) | ||
} | ||
return labourDay | ||
}, | ||
Observed: weekendAlt, | ||
} | ||
|
||
// StGeorgesDay represents St. George's Day on 6-May | ||
StGeorgesDay = &cal.Holiday{ | ||
Name: "Гергьовден, Ден на храбростта и Българската армия", | ||
Type: cal.ObservancePublic, | ||
Month: time.May, | ||
Day: 6, | ||
Func: cal.CalcDayOfMonth, | ||
Observed: weekendAlt, | ||
} | ||
|
||
// StCyrilAndMethodiusDay represents St. Cyril and St. Methodius Day on 24-May | ||
StCyrilAndMethodiusDay = &cal.Holiday{ | ||
Name: "Ден на светите братя Кирил и Методий, на българската азбука, просвета и култура и на славянската книжовност", | ||
Type: cal.ObservancePublic, | ||
Month: time.May, | ||
Day: 24, | ||
Func: cal.CalcDayOfMonth, | ||
Observed: weekendAlt, | ||
} | ||
|
||
// UnificationDay represents Unification Day on 6-Sep | ||
UnificationDay = &cal.Holiday{ | ||
Name: "Ден на Съединението", | ||
Type: cal.ObservancePublic, | ||
Month: time.September, | ||
Day: 6, | ||
Func: cal.CalcDayOfMonth, | ||
Observed: weekendAlt, | ||
} | ||
|
||
// IndependenceDay represents Independence Day on 22-Sep | ||
IndependenceDay = &cal.Holiday{ | ||
Name: "Ден на Независимостта на България", | ||
Type: cal.ObservancePublic, | ||
Month: time.September, | ||
Day: 22, | ||
Func: cal.CalcDayOfMonth, | ||
Observed: weekendAlt, | ||
} | ||
|
||
// ChristmasEve represents Christmas Eve 24-Dec | ||
ChristmasEve = &cal.Holiday{ | ||
Name: "Бъдни вечер", | ||
Type: cal.ObservancePublic, | ||
Month: time.December, | ||
Day: 24, | ||
Func: cal.CalcDayOfMonth, | ||
Observed: weekendAlt, | ||
} | ||
|
||
// ChristmasDay represents Christmas Day on 25-Dec | ||
ChristmasDay = aa.ChristmasDay.Clone(&cal.Holiday{Name: "Коледа", Type: cal.ObservancePublic, Observed: []cal.AltDay{ | ||
{Day: time.Saturday, Offset: 2}, | ||
{Day: time.Sunday, Offset: 2}, | ||
}}) | ||
|
||
// ChristmasDay2 represents Christmas Day 2 on 26-Dec | ||
ChristmasDay2 = aa.ChristmasDay2.Clone(&cal.Holiday{Name: "Коледа 2", Type: cal.ObservancePublic, Observed: []cal.AltDay{ | ||
{Day: time.Saturday, Offset: 2}, | ||
{Day: time.Sunday, Offset: 2}, | ||
{Day: time.Monday, Offset: 2}, | ||
{Day: time.Tuesday, Offset: 1}}}) | ||
|
||
// Holidays provides a list of the standard national holidays | ||
Holidays = []*cal.Holiday{ | ||
NewYear, | ||
LiberationDay, | ||
OrthodoxGoodFriday, | ||
OrthodoxEasterMonday, | ||
LabourDay, | ||
StGeorgesDay, | ||
StCyrilAndMethodiusDay, | ||
UnificationDay, | ||
IndependenceDay, | ||
ChristmasEve, | ||
ChristmasDay, | ||
ChristmasDay2, | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package bg | ||
|
||
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, 2018, d(2018, 1, 1), d(2018, 1, 1)}, | ||
{NewYear, 2019, d(2019, 1, 1), d(2019, 1, 1)}, | ||
{NewYear, 2020, d(2020, 1, 1), d(2020, 1, 1)}, | ||
{NewYear, 2021, d(2021, 1, 1), d(2021, 1, 1)}, | ||
{NewYear, 2022, d(2022, 1, 1), d(2022, 1, 3)}, | ||
{NewYear, 2023, d(2023, 1, 1), d(2023, 1, 2)}, | ||
|
||
{LiberationDay, 2018, d(2018, 3, 3), d(2018, 3, 5)}, | ||
{LiberationDay, 2019, d(2019, 3, 3), d(2019, 3, 4)}, | ||
{LiberationDay, 2020, d(2020, 3, 3), d(2020, 3, 3)}, | ||
{LiberationDay, 2021, d(2021, 3, 3), d(2021, 3, 3)}, | ||
{LiberationDay, 2022, d(2022, 3, 3), d(2022, 3, 3)}, | ||
{LiberationDay, 2023, d(2023, 3, 3), d(2023, 3, 3)}, | ||
|
||
{OrthodoxGoodFriday, 2018, d(2018, 4, 6), d(2018, 4, 6)}, | ||
{OrthodoxGoodFriday, 2019, d(2019, 4, 26), d(2019, 4, 26)}, | ||
{OrthodoxGoodFriday, 2020, d(2020, 4, 17), d(2020, 4, 17)}, | ||
{OrthodoxGoodFriday, 2021, d(2021, 4, 30), d(2021, 4, 30)}, | ||
{OrthodoxGoodFriday, 2022, d(2022, 4, 22), d(2022, 4, 22)}, | ||
{OrthodoxGoodFriday, 2023, d(2023, 4, 14), d(2023, 4, 14)}, | ||
|
||
{OrthodoxEasterMonday, 2018, d(2018, 4, 9), d(2018, 4, 9)}, | ||
{OrthodoxEasterMonday, 2019, d(2019, 4, 29), d(2019, 4, 29)}, | ||
{OrthodoxEasterMonday, 2020, d(2020, 4, 20), d(2020, 4, 20)}, | ||
{OrthodoxEasterMonday, 2021, d(2021, 5, 3), d(2021, 5, 3)}, | ||
{OrthodoxEasterMonday, 2022, d(2022, 4, 25), d(2022, 4, 25)}, | ||
{OrthodoxEasterMonday, 2023, d(2023, 4, 17), d(2023, 4, 17)}, | ||
|
||
{LabourDay, 2018, d(2018, 5, 1), d(2018, 5, 1)}, | ||
{LabourDay, 2019, d(2019, 5, 1), d(2019, 5, 1)}, | ||
{LabourDay, 2020, d(2020, 5, 1), d(2020, 5, 1)}, | ||
// Special case since OrthodoxEaster falls on that weekend | ||
{LabourDay, 2021, d(2021, 5, 4), d(2021, 5, 4)}, | ||
{LabourDay, 2022, d(2022, 5, 1), d(2022, 5, 2)}, | ||
{LabourDay, 2023, d(2023, 5, 1), d(2023, 5, 1)}, | ||
|
||
{StGeorgesDay, 2018, d(2018, 5, 6), d(2018, 5, 7)}, | ||
{StGeorgesDay, 2019, d(2019, 5, 6), d(2019, 5, 6)}, | ||
{StGeorgesDay, 2020, d(2020, 5, 6), d(2020, 5, 6)}, | ||
{StGeorgesDay, 2021, d(2021, 5, 6), d(2021, 5, 6)}, | ||
{StGeorgesDay, 2022, d(2022, 5, 6), d(2022, 5, 6)}, | ||
{StGeorgesDay, 2023, d(2023, 5, 6), d(2023, 5, 8)}, | ||
|
||
{StCyrilAndMethodiusDay, 2018, d(2018, 5, 24), d(2018, 5, 24)}, | ||
{StCyrilAndMethodiusDay, 2019, d(2019, 5, 24), d(2019, 5, 24)}, | ||
{StCyrilAndMethodiusDay, 2020, d(2020, 5, 24), d(2020, 5, 25)}, | ||
{StCyrilAndMethodiusDay, 2021, d(2021, 5, 24), d(2021, 5, 24)}, | ||
{StCyrilAndMethodiusDay, 2022, d(2022, 5, 24), d(2022, 5, 24)}, | ||
{StCyrilAndMethodiusDay, 2023, d(2023, 5, 24), d(2023, 5, 24)}, | ||
|
||
{UnificationDay, 2018, d(2018, 9, 6), d(2018, 9, 6)}, | ||
{UnificationDay, 2019, d(2019, 9, 6), d(2019, 9, 6)}, | ||
{UnificationDay, 2020, d(2020, 9, 6), d(2020, 9, 7)}, | ||
{UnificationDay, 2021, d(2021, 9, 6), d(2021, 9, 6)}, | ||
{UnificationDay, 2022, d(2022, 9, 6), d(2022, 9, 6)}, | ||
{UnificationDay, 2023, d(2023, 9, 6), d(2023, 9, 6)}, | ||
|
||
{IndependenceDay, 2018, d(2018, 9, 22), d(2018, 9, 24)}, | ||
{IndependenceDay, 2019, d(2019, 9, 22), d(2019, 9, 23)}, | ||
{IndependenceDay, 2020, d(2020, 9, 22), d(2020, 9, 22)}, | ||
{IndependenceDay, 2021, d(2021, 9, 22), d(2021, 9, 22)}, | ||
{IndependenceDay, 2022, d(2022, 9, 22), d(2022, 9, 22)}, | ||
{IndependenceDay, 2023, d(2023, 9, 22), d(2023, 9, 22)}, | ||
|
||
{ChristmasEve, 2018, d(2018, 12, 24), d(2018, 12, 24)}, | ||
{ChristmasEve, 2019, d(2019, 12, 24), d(2019, 12, 24)}, | ||
{ChristmasEve, 2020, d(2020, 12, 24), d(2020, 12, 24)}, | ||
{ChristmasEve, 2021, d(2021, 12, 24), d(2021, 12, 24)}, | ||
{ChristmasEve, 2022, d(2022, 12, 24), d(2022, 12, 26)}, | ||
{ChristmasEve, 2023, d(2023, 12, 24), d(2023, 12, 25)}, | ||
|
||
{ChristmasDay, 2018, d(2018, 12, 25), d(2018, 12, 25)}, | ||
{ChristmasDay, 2019, d(2019, 12, 25), d(2019, 12, 25)}, | ||
{ChristmasDay, 2020, d(2020, 12, 25), d(2020, 12, 25)}, | ||
{ChristmasDay, 2021, d(2021, 12, 25), d(2021, 12, 27)}, | ||
{ChristmasDay, 2022, d(2022, 12, 25), d(2022, 12, 27)}, | ||
{ChristmasDay, 2023, d(2023, 12, 25), d(2023, 12, 25)}, | ||
|
||
{ChristmasDay2, 2018, d(2018, 12, 26), d(2018, 12, 26)}, | ||
{ChristmasDay2, 2019, d(2019, 12, 26), d(2019, 12, 26)}, | ||
{ChristmasDay2, 2020, d(2020, 12, 26), d(2020, 12, 28)}, | ||
{ChristmasDay2, 2021, d(2021, 12, 26), d(2021, 12, 28)}, | ||
{ChristmasDay2, 2022, d(2022, 12, 26), d(2022, 12, 28)}, | ||
{ChristmasDay2, 2023, d(2023, 12, 26), d(2023, 12, 27)}, | ||
} | ||
|
||
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()) | ||
} | ||
} | ||
} |