Skip to content

Commit

Permalink
Merge pull request #140 from Alpa-1/feature/holidays-cyprus
Browse files Browse the repository at this point in the history
feat: Add holidays for Cyprus
  • Loading branch information
rickar authored Dec 3, 2024
2 parents 4285363 + fef1113 commit dc15b9d
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 0 deletions.
123 changes: 123 additions & 0 deletions v2/cy/cy_holidays.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// (c) Rick Arnold. Licensed under the BSD license (see LICENSE).

// Package cy provides holiday definitions for Cyprus.
package cy

import (
"time"

"github.com/rickar/cal/v2"
"github.com/rickar/cal/v2/aa"
)

var (
// Protochronia represents New Year's Day on 1-Jan
Protochronia = aa.NewYear.Clone(&cal.Holiday{Name: "Πρωτοχρονιά", Type: cal.ObservancePublic})

// Theofania represents Epiphany on 6-Jan
Theofania = aa.Epiphany.Clone(&cal.Holiday{Name: "Θεοφάνεια", Type: cal.ObservancePublic})

// KatharaDeftera represents Green Monday (movable, 48 days before Orthodox Easter Sunday)
KatharaDeftera = &cal.Holiday{
Name: "Καθαρά Δευτέρα",
Type: cal.ObservancePublic,
Func: cal.CalcEasterOffset,
Julian: true,
Offset: -48,
}

// EllinikiEpanastasi represents Greek Independence Day on 25-Mar
EllinikiEpanastasi = &cal.Holiday{
Name: "Ελληνική Επανάσταση",
Type: cal.ObservancePublic,
Month: time.March,
Day: 25,
Func: cal.CalcDayOfMonth,
}

// EthnikiEpetios represents National Day (EOKA Day) on 1-Apr
EthnikiEpetios = &cal.Holiday{
Name: "Εθνική Επέτειος",
Type: cal.ObservancePublic,
Month: time.April,
Day: 1,
Func: cal.CalcDayOfMonth,
}

// ErgatikoiProtomagia represents Labour Day on 1-May
ErgatikoiProtomagia = aa.WorkersDay.Clone(&cal.Holiday{Name: "Εργατική Πρωτομαγιά", Type: cal.ObservancePublic})

// MegaliParaskevi represents Orthodox Good Friday (movable Julian calendar-based)
MegaliParaskevi = &cal.Holiday{
Name: "Μεγάλη Παρασκευή",
Type: cal.ObservancePublic,
Func: func(h *cal.Holiday, year int) time.Time {
// Orthodox Good Friday is 2 days before Orthodox Easter Sunday
return cal.CalcEasterOffset(&cal.Holiday{Offset: -2, Julian: true}, year)
},
}

// DeuteraTouPascha represents Orthodox Easter Monday (Julian calendar-based)
DeuteraTouPascha = &cal.Holiday{
Name: "Δευτέρα του Πάσχα",
Type: cal.ObservancePublic,
Func: func(h *cal.Holiday, year int) time.Time {
// Orthodox Easter Monday is 1 day after Orthodox Easter Sunday
return cal.CalcEasterOffset(&cal.Holiday{Offset: 1, Julian: true}, year)
},
}

// AgiouPnevmatos represents Orthodox Whit Monday (movable, 50 days after Orthodox Easter Sunday)
AgiouPnevmatos = &cal.Holiday{
Name: "Αγίου Πνεύματος",
Type: cal.ObservancePublic,
Func: cal.CalcEasterOffset,
Julian: true,
Offset: 50,
}

// KoimisiTisTheotokou represents Assumption Day on 15-Aug
KoimisiTisTheotokou = aa.AssumptionOfMary.Clone(&cal.Holiday{Name: "Κοίμηση της Θεοτόκου", Type: cal.ObservancePublic})

// Anexartisia represents Cyprus Independence Day on 1-Oct
Anexartisia = &cal.Holiday{
Name: "Ανεξαρτησία της Κύπρου",
Type: cal.ObservancePublic,
Month: time.October,
Day: 1,
Func: cal.CalcDayOfMonth,
}

// EpeteiosTouOchi represents Ochi Day on 28-Oct
EpeteiosTouOchi = &cal.Holiday{
Name: "Επέτειος του Όχι",
Type: cal.ObservancePublic,
Month: time.October,
Day: 28,
Func: cal.CalcDayOfMonth,
}

// Christougenna represents Christmas Day on 25-Dec
Christougenna = aa.ChristmasDay.Clone(&cal.Holiday{Name: "Χριστούγεννα", Type: cal.ObservancePublic})

// DeyteriMeraTonChristougennon represents Boxing Day (Second Day of Christmas) on 26-Dec
DeyteriMeraTonChristougennon = aa.ChristmasDay2.Clone(&cal.Holiday{Name: "Δεύτερη Μέρα των Χριστουγέννων", Type: cal.ObservancePublic})

// Holidays provides a list of the standard national holidays
Holidays = []*cal.Holiday{
Protochronia,
Theofania,
KatharaDeftera,
EllinikiEpanastasi,
EthnikiEpetios,
ErgatikoiProtomagia,
MegaliParaskevi,
DeuteraTouPascha,
AgiouPnevmatos,
KoimisiTisTheotokou,
Anexartisia,
EpeteiosTouOchi,
Christougenna,
DeyteriMeraTonChristougennon,
}
)
89 changes: 89 additions & 0 deletions v2/cy/cy_holidays_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// (c) Rick Arnold. Licensed under the BSD license (see LICENSE).

package cy

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
}{
{Protochronia, 2024, d(2024, 1, 1), d(2024, 1, 1)},
{Protochronia, 2025, d(2025, 1, 1), d(2025, 1, 1)},
{Protochronia, 2026, d(2026, 1, 1), d(2026, 1, 1)},

{Theofania, 2024, d(2024, 1, 6), d(2024, 1, 6)},
{Theofania, 2025, d(2025, 1, 6), d(2025, 1, 6)},
{Theofania, 2026, d(2026, 1, 6), d(2026, 1, 6)},

{KatharaDeftera, 2024, d(2024, 3, 18), d(2024, 3, 18)},
{KatharaDeftera, 2025, d(2025, 3, 3), d(2025, 3, 3)},
{KatharaDeftera, 2026, d(2026, 2, 23), d(2026, 2, 23)},

{EllinikiEpanastasi, 2024, d(2024, 3, 25), d(2024, 3, 25)},
{EllinikiEpanastasi, 2025, d(2025, 3, 25), d(2025, 3, 25)},
{EllinikiEpanastasi, 2026, d(2026, 3, 25), d(2026, 3, 25)},

{EthnikiEpetios, 2024, d(2024, 4, 1), d(2024, 4, 1)},
{EthnikiEpetios, 2025, d(2025, 4, 1), d(2025, 4, 1)},
{EthnikiEpetios, 2026, d(2026, 4, 1), d(2026, 4, 1)},

{ErgatikoiProtomagia, 2024, d(2024, 5, 1), d(2024, 5, 1)},
{ErgatikoiProtomagia, 2025, d(2025, 5, 1), d(2025, 5, 1)},
{ErgatikoiProtomagia, 2026, d(2026, 5, 1), d(2026, 5, 1)},

{MegaliParaskevi, 2024, d(2024, 5, 3), d(2024, 5, 3)},
{MegaliParaskevi, 2025, d(2025, 4, 18), d(2025, 4, 18)},
{MegaliParaskevi, 2026, d(2026, 4, 10), d(2026, 4, 10)},

{DeuteraTouPascha, 2024, d(2024, 5, 6), d(2024, 5, 6)},
{DeuteraTouPascha, 2025, d(2025, 4, 21), d(2025, 4, 21)},
{DeuteraTouPascha, 2026, d(2026, 4, 13), d(2026, 4, 13)},

{AgiouPnevmatos, 2024, d(2024, 6, 24), d(2024, 6, 24)},
{AgiouPnevmatos, 2025, d(2025, 6, 9), d(2025, 6, 9)},
{AgiouPnevmatos, 2026, d(2026, 6, 1), d(2026, 6, 1)},

{KoimisiTisTheotokou, 2024, d(2024, 8, 15), d(2024, 8, 15)},
{KoimisiTisTheotokou, 2025, d(2025, 8, 15), d(2025, 8, 15)},
{KoimisiTisTheotokou, 2026, d(2026, 8, 15), d(2026, 8, 15)},

{Anexartisia, 2024, d(2024, 10, 1), d(2024, 10, 1)},
{Anexartisia, 2025, d(2025, 10, 1), d(2025, 10, 1)},
{Anexartisia, 2026, d(2026, 10, 1), d(2026, 10, 1)},

{EpeteiosTouOchi, 2024, d(2024, 10, 28), d(2024, 10, 28)},
{EpeteiosTouOchi, 2025, d(2025, 10, 28), d(2025, 10, 28)},
{EpeteiosTouOchi, 2026, d(2026, 10, 28), d(2026, 10, 28)},

{Christougenna, 2024, d(2024, 12, 25), d(2024, 12, 25)},
{Christougenna, 2025, d(2025, 12, 25), d(2025, 12, 25)},
{Christougenna, 2026, d(2026, 12, 25), d(2026, 12, 25)},

{DeyteriMeraTonChristougennon, 2024, d(2024, 12, 26), d(2024, 12, 26)},
{DeyteriMeraTonChristougennon, 2025, d(2025, 12, 26), d(2025, 12, 26)},
{DeyteriMeraTonChristougennon, 2026, d(2026, 12, 26), d(2026, 12, 26)},
}

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())
}
}
}

0 comments on commit dc15b9d

Please sign in to comment.