-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add specialdays sub-package to calculate public holidays and other sp…
…ecial days
- Loading branch information
1 parent
671d7fb
commit a1397b8
Showing
3 changed files
with
231 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,48 @@ | ||
package specialdays_test | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"simonwaldherr.de/go/golibs/specialdays" | ||
) | ||
|
||
func ExampleGetSpecialDays() { | ||
days := specialdays.GetSpecialDays(2019) | ||
|
||
keys := make([]string, 0, len(days)) | ||
|
||
for k := range days{ | ||
keys = append(keys, k) | ||
} | ||
sort.Strings(keys) | ||
|
||
for _, k := range keys { | ||
fmt.Printf("%s: %s\n", k, days[k].Format("2006-01-02")) | ||
} | ||
|
||
// Output: | ||
// 1. Weihnachtstag: 2019-12-25 | ||
// 2. Weihnachtstag: 2019-12-26 | ||
// Allerheiligen: 2019-11-01 | ||
// Buß- und Bettag: 2019-11-20 | ||
// Christi Himmelfahrt: 2019-05-30 | ||
// Fronleichnam: 2019-06-20 | ||
// Halloween: 2019-10-31 | ||
// Heiligabend: 2019-12-24 | ||
// Heilige Drei Könige: 2019-01-06 | ||
// Karfreitag: 2019-04-19 | ||
// Karnevalsbeginn: 2019-11-11 | ||
// Mariä Himmelfahrt: 2019-08-15 | ||
// Muttertag: 2019-05-12 | ||
// Neujahrstag: 2019-01-01 | ||
// Nikolaustag: 2019-12-06 | ||
// Ostermontag: 2019-04-22 | ||
// Ostersonntag: 2019-04-21 | ||
// Pfingstmontag: 2019-06-10 | ||
// Pfingstsonntag: 2019-06-09 | ||
// Silvester: 2019-12-31 | ||
// Tag der Arbeit: 2019-05-01 | ||
// Tag der Deutschen Einheit: 2019-10-03 | ||
// Valentinstag: 2019-02-14 | ||
// erster Advent: 2019-12-01 | ||
} |
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,108 @@ | ||
package specialdays | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
// CalculateEasterSunday berechnet den Ostersonntag für ein gegebenes Jahr. | ||
func CalculateEasterSunday(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 | ||
month := (h + l - 7*m + 114) / 31 | ||
day := ((h + l - 7*m + 114) % 31) + 1 | ||
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) | ||
} | ||
|
||
// CalculateMothersDay berechnet den Muttertag für ein gegebenes Jahr (2. Sonntag im Mai). | ||
func CalculateMothersDay(year int) time.Time { | ||
// Der 1. Mai des Jahres | ||
mayFirst := time.Date(year, time.May, 1, 0, 0, 0, 0, time.UTC) | ||
|
||
// Wochentag des 1. Mai berechnen | ||
weekday := mayFirst.Weekday() | ||
|
||
// Den ersten Sonntag im Mai finden | ||
daysUntilSunday := (7 - int(weekday)) % 7 | ||
firstSunday := mayFirst.AddDate(0, 0, daysUntilSunday) | ||
|
||
// Den zweiten Sonntag im Mai berechnen | ||
secondSunday := firstSunday.AddDate(0, 0, 7) | ||
|
||
return secondSunday | ||
} | ||
|
||
// CalculateFronleichnam berechnet Fronleichnam für ein gegebenes Jahr (60 Tage nach Ostern). | ||
func CalculateFronleichnam(year int) time.Time { | ||
easterSunday := CalculateEasterSunday(year) | ||
return easterSunday.AddDate(0, 0, 60) | ||
} | ||
|
||
// CalculateFirstAdvent berechnet den ersten Advent für ein gegebenes Jahr. | ||
func CalculateFirstAdvent(year int) time.Time { | ||
// Der erste Advent ist der Sonntag zwischen dem 27. November und dem 3. Dezember. | ||
firstAdvent := time.Date(year, time.December, 3, 0, 0, 0, 0, time.UTC) | ||
for firstAdvent.Weekday() != time.Sunday { | ||
firstAdvent = firstAdvent.AddDate(0, 0, -1) | ||
} | ||
return firstAdvent | ||
} | ||
|
||
// CalculateBussUndBettag berechnet den Buß- und Bettag für ein gegebenes Jahr. | ||
func CalculateBussUndBettag(year int) time.Time { | ||
// Der Buß- und Bettag ist der Mittwoch vor dem ersten Advent. | ||
firstAdvent := CalculateFirstAdvent(year) | ||
bussUndBettag := firstAdvent.AddDate(0, 0, -11) | ||
|
||
return bussUndBettag | ||
} | ||
|
||
// GetSpecialDays gibt eine Map mit allen besonderen Tagen für ein gegebenes Jahr zurück. | ||
func GetSpecialDays(year int) map[string]time.Time { | ||
specialDays := make(map[string]time.Time) | ||
|
||
// Statische Feiertage und besondere Tage | ||
specialDays["Neujahrstag"] = time.Date(year, 1, 1, 0, 0, 0, 0, time.UTC) | ||
specialDays["Tag der Arbeit"] = time.Date(year, 5, 1, 0, 0, 0, 0, time.UTC) | ||
specialDays["Tag der Deutschen Einheit"] = time.Date(year, 10, 3, 0, 0, 0, 0, time.UTC) | ||
specialDays["Nikolaustag"] = time.Date(year, time.December, 6, 0, 0, 0, 0, time.UTC) | ||
specialDays["Heiligabend"] = time.Date(year, 12, 24, 0, 0, 0, 0, time.UTC) | ||
specialDays["1. Weihnachtstag"] = time.Date(year, 12, 25, 0, 0, 0, 0, time.UTC) | ||
specialDays["2. Weihnachtstag"] = time.Date(year, 12, 26, 0, 0, 0, 0, time.UTC) | ||
specialDays["Silvester"] = time.Date(year, 12, 31, 0, 0, 0, 0, time.UTC) | ||
|
||
// Bewegliche Feiertage | ||
easterSunday := CalculateEasterSunday(year) | ||
specialDays["Karfreitag"] = easterSunday.AddDate(0, 0, -2) | ||
specialDays["Ostersonntag"] = easterSunday | ||
specialDays["Ostermontag"] = easterSunday.AddDate(0, 0, 1) | ||
specialDays["Christi Himmelfahrt"] = easterSunday.AddDate(0, 0, 39) | ||
specialDays["Pfingstsonntag"] = easterSunday.AddDate(0, 0, 49) | ||
specialDays["Pfingstmontag"] = easterSunday.AddDate(0, 0, 50) | ||
specialDays["Fronleichnam"] = easterSunday.AddDate(0, 0, 60) | ||
specialDays["erster Advent"] = CalculateFirstAdvent(year) | ||
|
||
// Andere besondere Tage | ||
specialDays["Valentinstag"] = time.Date(year, 2, 14, 0, 0, 0, 0, time.UTC) | ||
specialDays["Muttertag"] = CalculateMothersDay(year) | ||
specialDays["Halloween"] = time.Date(year, 10, 31, 0, 0, 0, 0, time.UTC) | ||
specialDays["Karnevalsbeginn"] = time.Date(year, 11, 11, 0, 0, 0, 0, time.UTC) | ||
|
||
// Weitere Feiertage | ||
specialDays["Heilige Drei Könige"] = time.Date(year, time.January, 6, 0, 0, 0, 0, time.UTC) | ||
specialDays["Fronleichnam"] = CalculateFronleichnam(year) | ||
specialDays["Mariä Himmelfahrt"] = time.Date(year, time.August, 15, 0, 0, 0, 0, time.UTC) | ||
specialDays["Allerheiligen"] = time.Date(year, time.November, 1, 0, 0, 0, 0, time.UTC) | ||
specialDays["Buß- und Bettag"] = CalculateBussUndBettag(year) | ||
|
||
return specialDays | ||
} |
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,75 @@ | ||
package specialdays | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
) | ||
|
||
// TestCalculateEasterSunday testet die Berechnung des Ostersonntags für verschiedene Jahre. | ||
func TestCalculateEasterSunday(t *testing.T) { | ||
testCases := []struct { | ||
year int | ||
expected time.Time | ||
}{ | ||
{2020, time.Date(2020, time.April, 12, 0, 0, 0, 0, time.UTC)}, | ||
{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)}, | ||
// Weitere Testfälle... | ||
} | ||
|
||
for _, tc := range testCases { | ||
calculatedDate := CalculateEasterSunday(tc.year) | ||
if !tc.expected.Equal(calculatedDate) { | ||
t.Errorf("Expected Easter Sunday of %d to be %v, but got %v", tc.year, tc.expected, calculatedDate) | ||
} | ||
} | ||
} | ||
|
||
// TestCalculateMothersDay testet die Berechnung des Muttertags für verschiedene Jahre. | ||
func TestCalculateMothersDay(t *testing.T) { | ||
testCases := []struct { | ||
year int | ||
expected time.Time | ||
}{ | ||
{2020, time.Date(2020, time.May, 10, 0, 0, 0, 0, time.UTC)}, | ||
{2024, time.Date(2024, time.May, 12, 0, 0, 0, 0, time.UTC)}, | ||
{2025, time.Date(2025, time.May, 11, 0, 0, 0, 0, time.UTC)}, | ||
{2026, time.Date(2026, time.May, 10, 0, 0, 0, 0, time.UTC)}, | ||
// Weitere Testfälle... | ||
} | ||
|
||
for _, tc := range testCases { | ||
calculatedDate := CalculateMothersDay(tc.year) | ||
if !tc.expected.Equal(calculatedDate) { | ||
t.Errorf("Expected Mothers Day of %d to be %v, but got %v", tc.year, tc.expected, calculatedDate) | ||
} | ||
} | ||
} | ||
|
||
// TestGetSpecialDays testet die Map der besonderen Tage für ein bestimmtes Jahr. | ||
func TestGetSpecialDays(t *testing.T) { | ||
year := 2024 | ||
specialDays := GetSpecialDays(year) | ||
|
||
testCases := []struct { | ||
name string | ||
expected time.Time | ||
}{ | ||
{"Neujahrstag", time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC)}, | ||
{"Tag der Arbeit", time.Date(year, time.May, 1, 0, 0, 0, 0, time.UTC)}, | ||
{"Tag der Deutschen Einheit", time.Date(year, time.October, 3, 0, 0, 0, 0, time.UTC)}, | ||
{"Heiligabend", time.Date(year, time.December, 24, 0, 0, 0, 0, time.UTC)}, | ||
// Weitere Testfälle... | ||
} | ||
|
||
for _, tc := range testCases { | ||
if date, ok := specialDays[tc.name]; ok { | ||
if !tc.expected.Equal(date) { | ||
t.Errorf("Expected %s to be %v, but got %v", tc.name, tc.expected, date) | ||
} | ||
} else { | ||
t.Errorf("Expected %s to be in special days map", tc.name) | ||
} | ||
} | ||
} |