init
This commit is contained in:
commit
f3824d4e42
16
Readme.md
Normal file
16
Readme.md
Normal file
@ -0,0 +1,16 @@
|
||||
This is little library to operate with bank holidays in Poland.
|
||||
|
||||
```go
|
||||
|
||||
import "git.ma-al.com/goc_marek/holidayspl"
|
||||
|
||||
holidays := holidayspl.New()
|
||||
|
||||
// to get list of all holidays
|
||||
holidays.GetHolidaysList(d.Year())
|
||||
|
||||
// get holiday by date or false as second returned value
|
||||
hh, ok := holidays.GetByDate(time.Date(2024, time.March, 31, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
```
|
||||
For more info just look at th tests file.
|
170
holidays.go
Normal file
170
holidays.go
Normal file
@ -0,0 +1,170 @@
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
69
holidays_test.go
Normal file
69
holidays_test.go
Normal file
@ -0,0 +1,69 @@
|
||||
package holidayspl_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.ma-al.com/goc_marek/holidayspl"
|
||||
)
|
||||
|
||||
func TestGetEasterDate(t *testing.T) {
|
||||
holidays := holidayspl.New()
|
||||
|
||||
tests := []struct {
|
||||
year int
|
||||
expected time.Time
|
||||
}{
|
||||
{2024, time.Date(2024, time.March, 31, 0, 0, 0, 0, time.UTC)},
|
||||
{2025, time.Date(2025, time.April, 20, 0, 0, 0, 0, time.UTC)},
|
||||
{2026, time.Date(2026, time.April, 5, 0, 0, 0, 0, time.UTC)},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := holidays.GetEasterDate(test.year)
|
||||
if !result.Equal(test.expected) {
|
||||
t.Errorf("GetEasterDate(%d) = %v; want %v", test.year, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetByDate(t *testing.T) {
|
||||
holidays := holidayspl.New()
|
||||
|
||||
tests := []struct {
|
||||
date time.Time
|
||||
expected string
|
||||
found bool
|
||||
}{
|
||||
{time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC), "New Year", true},
|
||||
{time.Date(2024, time.March, 31, 0, 0, 0, 0, time.UTC), "Easter Sunday", true},
|
||||
{time.Date(2024, time.December, 25, 0, 0, 0, 0, time.UTC), "Christmas", true},
|
||||
{time.Date(2024, time.August, 15, 0, 0, 0, 0, time.UTC), "Assumption of Mary", true},
|
||||
{time.Date(2024, time.July, 4, 0, 0, 0, 0, time.UTC), "", false}, // No holiday on this date
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result, found := holidays.GetByDate(test.date)
|
||||
if found != test.found {
|
||||
t.Errorf("GetByDate(%v) = %v; want %v", test.date, found, test.found)
|
||||
}
|
||||
if found && result.Name != test.expected {
|
||||
t.Errorf("GetByDate(%v) = %v; want %v", test.date, result.Name, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCaching(t *testing.T) {
|
||||
holidays := holidayspl.New()
|
||||
|
||||
year := 2024
|
||||
// First call should calculate and cache holidays for the year
|
||||
holidays.GetHolidaysList(year)
|
||||
// Modify the cache and see if the function returns the cached value
|
||||
holidays.GetCache()[year][0].Name = "Modified New Year"
|
||||
|
||||
result := holidays.GetHolidaysList(year)
|
||||
if result[0].Name != "Modified New Year" {
|
||||
t.Errorf("Caching not working properly. Got %v, expected %v", result[0].Name, "Modified New Year")
|
||||
}
|
||||
}
|
24
models.go
Normal file
24
models.go
Normal file
@ -0,0 +1,24 @@
|
||||
package holidayspl
|
||||
|
||||
import "time"
|
||||
|
||||
type HolidayType int
|
||||
|
||||
const (
|
||||
FIXED HolidayType = iota
|
||||
MOVABLE
|
||||
)
|
||||
|
||||
func (d HolidayType) String() string {
|
||||
return [...]string{"fixed", "movable"}[d]
|
||||
}
|
||||
|
||||
type Holiday struct {
|
||||
Name string
|
||||
NamePL string
|
||||
Month time.Month
|
||||
Day int
|
||||
HolidayType HolidayType
|
||||
PlusEaster int
|
||||
Date time.Time
|
||||
}
|
Loading…
Reference in New Issue
Block a user