From 3b1dd7a2df8a227d1930063c39bc042a2a974ef0 Mon Sep 17 00:00:00 2001 From: nicobock Date: Tue, 25 Oct 2022 17:20:18 +0200 Subject: [PATCH 1/4] Improved markdown compatibility --- README.md | 68 +++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 8973116..e7b6b6e 100644 --- a/README.md +++ b/README.md @@ -17,46 +17,46 @@ in the requested year plus the name of the holiday. `` may be any of t |||| |----|-----|----| -`Neujahr` | `Epiphanias` | `HeiligeDreiKönige` -`Valentinstag` | `InternationalerTagDesGedenkensAnDieOpferDesHolocaust` | `Josefitag` -`Weiberfastnacht` | `Karnevalssonntag` | `Rosenmontag` -`Fastnacht` | `Aschermittwoch` | `InternationalerFrauentag` -`Palmsonntag` | `Gründonnerstag` | `Karfreitag` -`Ostern` | `BeginnSommerzeit` | `Ostermontag` -`Walpurgisnacht` | `TagDerArbeit` | `TagDerBefreiung` -`Staatsfeiertag` | `InternationalerTagDerPressefreiheit` | `Florianitag` -`Muttertag` | `Handtuchtag` | `ChristiHimmelfahrt` - `Vatertag` | `Pfingsten` | `Pfingstmontag` -`Dreifaltigkeitssonntag` | `Fronleichnam` | `TagDesMeeres` -`MariäHimmelfahrt` | `SystemAdministratorAppreciationDay` |`Rupertitag` -`InternationalerKindertag`| `Weltflüchtlingstag` | `TagDerDeutschenEinheit` -`TagDerVolksabstimmung` | `Nationalfeiertag` | `Erntedankfest` -`Reformationstag` | `Halloween` | `BeginnWinterzeit` -`Allerheiligen` | `Allerseelen` | `Martinstag` -`Karnevalsbeginn` | `Leopolditag` | `Weltkindertag` -`BußUndBettag` | `Thanksgiving` | `Blackfriday` -`Volkstrauertag` | `Nikolaus` | `MariäUnbefleckteEmpfängnis` -`MariäEmpfängnis` | `Totensonntag` | `ErsterAdvent` -`ZweiterAdvent` | `DritterAdvent` | `VierterAdvent` -`Heiligabend` | `Weihnachten` | `Christtag` -`Stefanitag` | `ZweiterWeihnachtsfeiertag` | `Silvester` +|`Neujahr` | `Epiphanias` | `HeiligeDreiKönige`| +|`Valentinstag` | `InternationalerTagDesGedenkensAnDieOpferDesHolocaust` | `Josefitag`| +|`Weiberfastnacht` | `Karnevalssonntag` | `Rosenmontag`| +|`Fastnacht` | `Aschermittwoch` | `InternationalerFrauentag`| +|`Palmsonntag` | `Gründonnerstag` | `Karfreitag`| +|`Ostern` | `BeginnSommerzeit` | `Ostermontag`| +|`Walpurgisnacht` | `TagDerArbeit` | `TagDerBefreiung`| +|`Staatsfeiertag` | `InternationalerTagDerPressefreiheit` | `Florianitag`| +|`Muttertag` | `Handtuchtag` | `ChristiHimmelfahrt`| +| `Vatertag` | `Pfingsten` | `Pfingstmontag`| +|`Dreifaltigkeitssonntag` | `Fronleichnam` | `TagDesMeeres`| +|`MariäHimmelfahrt` | `SystemAdministratorAppreciationDay` |`Rupertitag`| +|`InternationalerKindertag`| `Weltflüchtlingstag` | `TagDerDeutschenEinheit`| +|`TagDerVolksabstimmung` | `Nationalfeiertag` | `Erntedankfest`| +|`Reformationstag` | `Halloween` | `BeginnWinterzeit`| +|`Allerheiligen` | `Allerseelen` | `Martinstag`| +|`Karnevalsbeginn` | `Leopolditag` | `Weltkindertag`| +|`BußUndBettag` | `Thanksgiving` | `Blackfriday`| +|`Volkstrauertag` | `Nikolaus` | `MariäUnbefleckteEmpfängnis`| +|`MariäEmpfängnis` | `Totensonntag` | `ErsterAdvent`| +|`ZweiterAdvent` | `DritterAdvent` | `VierterAdvent`| +|`Heiligabend` | `Weihnachten` | `Christtag`| +|`Stefanitag` | `ZweiterWeihnachtsfeiertag` | `Silvester`| `` returns an object of type `region`. It offers a list of public holidays valid in the specified state as well as the name and the shortname of the state as attributes. `` may be any of: |||| -----|-----|---- -`BadenWürttemberg` | `Bayern` | `Berlin` -`Brandenburg` | `Bremen` | `Hamburg` -`Hessen` | `MecklenburgVorpommern` | `Niedersachsen` -`NordrheinWestfalen` | `RheinlandPfalz` | `Saarland` -`Sachsen` | `SachsenAnhalt` | `SchleswigHolstein` -`Thüringen` | `Deutschland` | `Burgenland` -`Kärnten` | `Niederösterreich` | `Oberösterreich` -`Salzburg` | `Steiermark` | `Tirol` -`Vorarlberg` | `Wien` | `Österreich` -`All` |   |   +|----|-----|----| +|`BadenWürttemberg` | `Bayern` | `Berlin`| +|`Brandenburg` | `Bremen` | `Hamburg`| +|`Hessen` | `MecklenburgVorpommern` | `Niedersachsen`| +|`NordrheinWestfalen` | `RheinlandPfalz` | `Saarland`| +|`Sachsen` | `SachsenAnhalt` | `SchleswigHolstein`| +|`Thüringen` | `Deutschland` | `Burgenland`| +|`Kärnten` | `Niederösterreich` | `Oberösterreich`| +|`Salzburg` | `Steiermark` | `Tirol`| +|`Vorarlberg` | `Wien` | `Österreich`| +|`All` |   |  | The optional region function argument `includingSundays` switches the behavior of the region function to include "gesetzliche Feiertage" that fall on Sundays in its output. This is important in Brandenburg, particularly for Easter and Pentecost Sunday. If you are calculating shift costs you will need to know even the holidays "hidden by Sunday". From 22ed95a36fc9e80df7ed016e0ee8df9812694507 Mon Sep 17 00:00:00 2001 From: nicobock Date: Tue, 25 Oct 2022 17:22:34 +0200 Subject: [PATCH 2/4] Added parse region from string method --- region.go | 66 ++++++++++++++++++++++++++++++++++ region_test.go | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) diff --git a/region.go b/region.go index 3234591..5dcf667 100644 --- a/region.go +++ b/region.go @@ -2,6 +2,7 @@ package feiertage import ( "fmt" + "github.com/pkg/errors" "sort" "strings" ) @@ -372,3 +373,68 @@ func GetAllRegions(year int, inklSonntag bool, country ...string) (regions []Reg return regions } + +func GetRegionFromString(region string, y int) (Region, error) { + + region = strings.ToLower(region) + region = strings.ReplaceAll(region, " ", "") + region = strings.ReplaceAll(region, "-", "") + region = strings.ReplaceAll(region, "ä", "ae") + region = strings.ReplaceAll(region, "ü", "ue") + region = strings.ReplaceAll(region, "ö", "oe") + switch region { + case "badenwuerttemberg": + return BadenWürttemberg(y), nil + case "bayern": + return Bayern(y), nil + case "berlin": + return Berlin(y), nil + case "brandenburg": + return Brandenburg(y), nil + case "bremen": + return Bremen(y), nil + case "hamburg": + return Hamburg(y), nil + case "hessen": + return Hessen(y), nil + case "mecklenburgvorpommern": + return MecklenburgVorpommern(y), nil + case "niedersachsen": + return Niedersachsen(y), nil + case "nordrheinwestfalen": + return NordrheinWestfalen(y), nil + case "rheinlandpfalz": + return RheinlandPfalz(y), nil + case "saarland": + return Saarland(y), nil + case "sachsen": + return Sachsen(y), nil + case "sachsenanhalt": + return SachsenAnhalt(y), nil + case "schleswigholstein": + return SchleswigHolstein(y), nil + case "thueringen": + return Thüringen(y), nil + case "burgenland": + return Burgenland(y), nil + case "kaernten": + return Kärnten(y), nil + case "niederoesterreich": + return Niederösterreich(y), nil + case "oberoesterreich": + return Oberösterreich(y), nil + case "salzburg": + return Salzburg(y), nil + case "steiermark": + return Steiermark(y), nil + case "tirol": + return Tirol(y), nil + case "vorarlberg": + return Vorarlberg(y), nil + case "wien": + return Wien(y), nil + case "oesterreich": + return Österreich(y), nil + } + return Region{}, errors.New(fmt.Sprintf("Not found region for: '%s'", region)) +} diff --git a/region_test.go b/region_test.go index 11fe551..8e1f322 100644 --- a/region_test.go +++ b/region_test.go @@ -2,6 +2,7 @@ package feiertage import ( "fmt" + "github.com/stretchr/testify/assert" "testing" ) @@ -92,3 +93,99 @@ func TestFeiertageZahl(t *testing.T) { fmt.Println(Brandenburg(2017)) } + +func TestGetRegionFromString(t *testing.T) { + _, err := GetRegionFromString("", 2022) + assert.Error(t, err) + _, err = GetRegionFromString("Sachen-Anhalt", 2022) + assert.Error(t, err) + + region, err := GetRegionFromString("Sachsen-Anhalt", 2022) + assert.Equal(t, region, SachsenAnhalt(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Sachsen Anhalt", 2022) + assert.Equal(t, region, SachsenAnhalt(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("SachsenAnhalt", 2022) + assert.Equal(t, region, SachsenAnhalt(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Baden Württemberg", 2022) + assert.Equal(t, region, BadenWürttemberg(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Bayern", 2022) + assert.Equal(t, region, Bayern(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("bayern", 2022) + assert.Equal(t, region, Bayern(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Berlin", 2022) + assert.Equal(t, region, Berlin(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Brandenburg", 2022) + assert.Equal(t, region, Brandenburg(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Bremen", 2022) + assert.Equal(t, region, Bremen(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Hamburg", 2022) + assert.Equal(t, region, Hamburg(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Niedersachsen", 2022) + assert.Equal(t, region, Niedersachsen(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("NordrheinWestfalen", 2022) + assert.Equal(t, region, NordrheinWestfalen(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("RheinlandPfalz", 2022) + assert.Equal(t, region, RheinlandPfalz(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Saarland", 2022) + assert.Equal(t, region, Saarland(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Sachsen", 2022) + assert.Equal(t, region, Sachsen(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("SachsenAnhalt", 2022) + assert.Equal(t, region, SachsenAnhalt(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("SchleswigHolstein", 2022) + assert.Equal(t, region, SchleswigHolstein(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Thüringen", 2022) + assert.Equal(t, region, Thüringen(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Thüringen", 2022) + assert.Equal(t, region, Thüringen(2022)) + + region, err = GetRegionFromString("Burgenland", 2022) + assert.Equal(t, region, Burgenland(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Kärnten", 2022) + assert.Equal(t, region, Kärnten(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Niederösterreich", 2022) + assert.Equal(t, region, Niederösterreich(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Oberösterreich", 2022) + assert.Equal(t, region, Oberösterreich(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Salzburg", 2022) + assert.Equal(t, region, Salzburg(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Steiermark", 2022) + assert.Equal(t, region, Steiermark(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Tirol", 2022) + assert.Equal(t, region, Tirol(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Vorarlberg", 2022) + assert.Equal(t, region, Vorarlberg(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Wien", 2022) + assert.Equal(t, region, Wien(2022)) + assert.NoError(t, err) + region, err = GetRegionFromString("Österreich", 2022) + assert.Equal(t, region, Österreich(2022)) + assert.NoError(t, err) + +} From a6db1027bfade6820a1fdbd86e08b930ddbd8838 Mon Sep 17 00:00:00 2001 From: nicobock Date: Tue, 25 Oct 2022 17:22:43 +0200 Subject: [PATCH 3/4] Added parse region from string method --- go.mod | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/go.mod b/go.mod index c1b2561..f91d83e 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module github.com/wlbr/feiertage go 1.15 + +require ( + github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.8.1 +) From 5ae7ed85aec0ae1671f5b44e6f01e33294c14c71 Mon Sep 17 00:00:00 2001 From: nicobock Date: Tue, 25 Oct 2022 17:24:03 +0200 Subject: [PATCH 4/4] Added check Time method to Module and updatet Docs --- README.md | 30 +++++++++++++++++++++++++++++- checkBackHoliday.go | 38 ++++++++++++++++++++++++++++++++++++++ checkBackHoliday_test.go | 20 ++++++++++++++++++++ cmd/feiertage/feiertage.go | 2 +- 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 checkBackHoliday.go create mode 100644 checkBackHoliday_test.go diff --git a/README.md b/README.md index e7b6b6e..bc6dbb6 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,12 @@ The library is probably useful only for people realizing use cases with special See https://godoc.org/github.com/wlbr/feiertage ### Usage: -There are two types of functions: +There are four types of functions: * `(year)` and * `(year optional:IncludingSundays:true)` + * `GetRegionFromString(region, year)` + * `CheckIfIsBankHolidayIn(date, state)` `` returns an extended `time` object (type `feiertag`). It carries the date of the holiday in the requested year plus the name of the holiday. `` may be any of the following: @@ -67,6 +69,13 @@ schools etc. are generally closed but workers don't get the day off by default. include these days in your planning, it's okay to reference `Österreich` instead, as legal holidays are (more or less) synchronised across all Austrian states (Bundesländer). + +GetRegionFromString tries to match a string to a region from Germany or Austria. Because a reagion already contains the feiertage, a `year` is needed to calc theese. + +CheckIfIsBankHolidayIn checks if the given `date` is a Bank holiday in the `region`, Sundays are only positve in case they are on a feiertag for the region as well. + + + ### Examples: fmt.Println(Ostern(2016)) @@ -107,6 +116,25 @@ include these days in your planning, it's okay to reference `Österreich` instea 25.12.2016 Weihnachten 26.12.2016 Zweiter Weihnachtsfeiertag + region, _ := GetRegionFromString("Brandenburg",2016) + fmt.Println(region) + --> Brandenburg (BB) + 01.01.2016 Neujahr + 25.03.2016 Karfreitag + 28.03.2016 Ostermontag + 01.05.2016 Tag der Arbeit + 05.05.2016 Christi Himmelfahrt + 16.05.2016 Pfingstmontag + 03.10.2016 Tag der deutschen Einheit + 31.10.2016 Reformationstag + 25.12.2016 Weihnachten + 26.12.2016 Zweiter Weihnachtsfeiertag + + fmt.Println(CheckIfIsBankHolidayIn(time.Date(2016,1,1,0,0,0,0,time.UTC),Brandenburg(2016, false))) + --> true + + + ## Command line tool diff --git a/checkBackHoliday.go b/checkBackHoliday.go new file mode 100644 index 0000000..49a7293 --- /dev/null +++ b/checkBackHoliday.go @@ -0,0 +1,38 @@ +package feiertage + +import ( + "github.com/pkg/errors" + "time" +) + +func CheckIfIsBankHoliday(date time.Time, region Region) bool { + + for _, feiertag := range region.Feiertage { + if datesAreEqual(feiertag.Time, date) { + return true + } + } + return false + +} + +func datesAreEqual(date1, date2 time.Time) bool { + if date1.Year() != date2.Year() { + return false + } + if date1.Month() != date2.Month() { + return false + } + if date1.Day() != date2.Day() { + return false + } + return true +} +func CheckIfIsBankHolidayIn(date time.Time, state string) (bool, error) { + + region, err := GetRegionFromString(state, date.Year()) + if err != nil { + return false, errors.Wrap(err, "Failed to parse region from state string") + } + return CheckIfIsBankHoliday(date, region), nil +} diff --git a/checkBackHoliday_test.go b/checkBackHoliday_test.go new file mode 100644 index 0000000..8880f8d --- /dev/null +++ b/checkBackHoliday_test.go @@ -0,0 +1,20 @@ +package feiertage + +import ( + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestCheckIfIsBankHoliday(t *testing.T) { + isBankHoliday := CheckIfIsBankHoliday(time.Date(2022, 10, 31, 0, 0, 0, 0, time.UTC), Niedersachsen(2022)) + assert.True(t, isBankHoliday) + isBankHoliday = CheckIfIsBankHoliday(time.Date(2022, 12, 25, 0, 0, 0, 0, time.UTC), Niedersachsen(2022)) + assert.True(t, isBankHoliday) + isBankHoliday = CheckIfIsBankHoliday(time.Date(2022, 12, 26, 0, 0, 0, 0, time.UTC), Niedersachsen(2022)) + assert.True(t, isBankHoliday) + isBankHoliday = CheckIfIsBankHoliday(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), Niedersachsen(2023)) + assert.True(t, isBankHoliday) + isBankHoliday = CheckIfIsBankHoliday(time.Date(2022, 10, 30, 0, 0, 0, 0, time.UTC), Niedersachsen(2022)) + assert.False(t, isBankHoliday) +} diff --git a/cmd/feiertage/feiertage.go b/cmd/feiertage/feiertage.go index 7f31f63..54c08e2 100644 --- a/cmd/feiertage/feiertage.go +++ b/cmd/feiertage/feiertage.go @@ -36,7 +36,7 @@ func getRegion(region string, year int, includingSundays bool) (feiertage.Region return r, nil } } - return r, fmt.Errorf("Region '%s' unbekannt.", region) + return r, fmt.Errorf("Region '%s' unknown", region) } func main() {