package holidayspl import ( "time" ) type Holidays struct { list []Holiday cache map[int][]Holiday } func New() *Holidays { return &Holidays{ list: createList(), cache: make(map[int][]Holiday), } } func (hol *Holidays) GetEasterDate(year int) time.Time { a := year % 19 b := year / 100 c := year % 100 d := b / 4 e := b % 4 f := (b + 8) / 25 g := (b - f + 1) / 3 h := (19*a + b - d - g + 15) % 30 i := c / 4 k := c % 4 l := (32 + 2*e + 2*i - h - k) % 7 m := (a + 11*h + 22*l) / 451 n := (h + l - 7*m + 114) / 31 o := (h + l - 7*m + 114) % 31 return time.Date(year, time.Month(n), o+1, 0, 0, 0, 0, time.UTC) } func (hol *Holidays) GetHolidaysList(year int) []Holiday { // Check if the holiday list for this year is already cached if holidays, ok := hol.cache[year]; ok { return holidays } // Calculate and store holidays in the cache easter := hol.GetEasterDate(year) for i, h := range hol.list { if h.HolidayType == FIXED { hol.list[i].Date = time.Date(year, h.Month, h.Day, 0, 0, 0, 0, time.UTC) } else if h.HolidayType == MOVABLE { hol.list[i].Date = easter.AddDate(0, 0, h.PlusEaster) } } // Cache the computed holiday list hol.cache[year] = hol.list return hol.list } func (hol *Holidays) GetByDate(d time.Time) (Holiday, bool) { for _, h := range hol.GetHolidaysList(d.Year()) { if h.Date.Equal(d) { return h, true } } return Holiday{}, false } func (hol *Holidays) GetCache() map[int][]Holiday { return hol.cache } func createList() []Holiday { return []Holiday{ { Name: "New Year", NamePL: "Nowy Rok", Month: time.Month(1), Day: 1, HolidayType: FIXED, }, { Name: "Three Kings' Day", NamePL: "Święto Trzech Króli", Month: time.Month(1), Day: 6, HolidayType: FIXED, }, { Name: "Labour Day", NamePL: "Święto Pracy", Month: time.Month(5), Day: 1, HolidayType: FIXED, }, { Name: "3 May Constitution Day", NamePL: "Narodowe Święto Konstytucji Trzeciego Maja", Month: time.Month(5), Day: 3, HolidayType: FIXED, }, { Name: "Assumption of Mary", NamePL: "Wniebowzięcie Najświętszej Maryi Panny", Month: time.Month(8), Day: 15, HolidayType: FIXED, }, { Name: "All Saints' Day", NamePL: "Wszystkich Świętych", Month: time.Month(11), Day: 1, HolidayType: FIXED, }, { Name: "National Independence Day", NamePL: "Narodowe Święto Niepodległości", Month: time.Month(11), Day: 11, HolidayType: FIXED, }, { Name: "Christmas", NamePL: "Boże Narodzenie", Month: time.Month(12), Day: 25, HolidayType: FIXED, }, { Name: "Second Day of Christmas", NamePL: "Boże Narodzenie - drugi dzień", Month: time.Month(12), Day: 26, HolidayType: FIXED, }, { Name: "Easter Sunday", NamePL: "Niedziela Wielkanocna", Month: time.Month(5), Day: 3, HolidayType: MOVABLE, PlusEaster: 0, }, { Name: "Easter Monday", NamePL: "Poniedziałek Wielkanocny", Month: time.Month(5), Day: 3, HolidayType: MOVABLE, PlusEaster: 1, }, { Name: "Green Week", NamePL: "Zielone Świątki", Month: time.Month(5), Day: 3, HolidayType: MOVABLE, PlusEaster: 49, }, { Name: "Feast of Corpus Christi", NamePL: "Boże Ciało", Month: time.Month(5), Day: 3, HolidayType: MOVABLE, PlusEaster: 60, }, } }