Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public EN_NZHolidayStrategy()
this.InnerHolidays.Add(ChristianHolidays.EasterMonday);
this.InnerHolidays.Add(AnzacDay);
this.InnerHolidays.Add(QueensBirthday);
this.InnerHolidays.Add(Matariki);
this.InnerHolidays.Add(LabourDay);
this.InnerHolidays.Add(ChristianHolidays.Christmas);
this.InnerHolidays.Add(GlobalHolidays.BoxingDay);
Expand All @@ -36,7 +37,18 @@ protected override IDictionary<DateTime, Holiday> BuildObservancesMap(int year)
var date = innerHoliday.GetInstance(year);
if (date.HasValue)
{
holidayMap.Add(date.Value, innerHoliday);
// If the holiday already exists in the map, combine the two holidays.
// This is apparent for Easter Monday/Anzac Day on 25 April 2011.
if (holidayMap.TryGetValue(date.Value, out var existingHoliday))
{
var combinedHoliday = new FixedHoliday($"{existingHoliday.Name}/{innerHoliday.Name}",
date.Value.Month, date.Value.Day);
holidayMap[date.Value] = combinedHoliday;
}
else
{
holidayMap.Add(date.Value, innerHoliday);
}

// New Year, Day After New Year, Christmas and Boxing Days are 'Mondayised'
// ie if these dates fall on a weekday then they are observed on the actual day.
Expand Down Expand Up @@ -148,6 +160,42 @@ public static Holiday QueensBirthday
}
}

// Some Friday on June or July - Matariki
private static Holiday matariki;
private static Holiday Matariki
{
get
{
if (matariki == null)
{
// Matariki doesn't have a readily-available algorithm and its dates have been calulated up to
// 2052 by the Matariki Advisory Committee.
// See https://www.mbie.govt.nz/assets/matariki-dates-2022-to-2052-matariki-advisory-group.pdf

var knownMatarikiOccurences = new Dictionary<int, DayInYear>
{
{2022, new DayInYear(6, 24)},
{2023, new DayInYear(7, 14)},
{2024, new DayInYear(6, 28)},
{2025, new DayInYear(6, 20)},
{2026, new DayInYear(7, 10)},
{2027, new DayInYear(6, 25)},
{2028, new DayInYear(7, 14)},
{2029, new DayInYear(7, 6)},
{2030, new DayInYear(6, 21)},
{2031, new DayInYear(7, 11)},
{2032, new DayInYear(7, 2)},
{2033, new DayInYear(6, 24)},
{2034, new DayInYear(7, 7)},
{2035, new DayInYear(6, 29)}
};

matariki = new YearMapHoliday("Matariki", knownMatarikiOccurences);
}
return matariki;
}
}

// 4th Monday in October - Labour Day
private static Holiday labourDay;

Expand Down
56 changes: 55 additions & 1 deletion tests/DateTimeExtensions.Tests/en-NZCalendarTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ public void NewYearsDay()
{
var workingDayCultureInfo = new WorkingDayCultureInfo("en-NZ");

var dateOnGregorian = new DateTime(2013, 1, 1);
var dateOnGregorian = new DateTime(2011, 1, 1);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
dateOnGregorian = new DateTime(2012, 1, 1);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
dateOnGregorian = new DateTime(2013, 1, 1);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
dateOnGregorian = new DateTime(2014, 1, 1);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
Expand Down Expand Up @@ -58,6 +62,54 @@ public void DayAfterNewYearsDay()
TestHoliday(workingDayCultureInfo, dateOnGregorian);
}

[Test]
public void EasterAnzacClash()
{
var workingDayCultureInfo = new WorkingDayCultureInfo("en-NZ");

var holidays = workingDayCultureInfo.GetHolidaysOfYear(2010);
Assert.IsTrue(holidays.Any(h => h.Name == "Easter Monday"));
Assert.IsTrue(holidays.Any(h => h.Name == "Anzac Day"));
Assert.IsFalse(holidays.Any(h => h.Name == "Easter Monday/Anzac Day"));

holidays = workingDayCultureInfo.GetHolidaysOfYear(2011);
Assert.IsFalse(holidays.Any(h => h.Name == "Easter Monday"));
Assert.IsFalse(holidays.Any(h => h.Name == "Anzac Day"));
Assert.IsTrue(holidays.Any(h => h.Name == "Easter Monday/Anzac Day"));

holidays = workingDayCultureInfo.GetHolidaysOfYear(2012);
Assert.IsTrue(holidays.Any(h => h.Name == "Easter Monday"));
Assert.IsTrue(holidays.Any(h => h.Name == "Anzac Day"));
Assert.IsFalse(holidays.Any(h => h.Name == "Easter Monday/Anzac Day"));

holidays = workingDayCultureInfo.GetHolidaysOfYear(2095);
Assert.IsFalse(holidays.Any(h => h.Name == "Easter Monday"));
Assert.IsFalse(holidays.Any(h => h.Name == "Anzac Day"));
Assert.IsTrue(holidays.Any(h => h.Name == "Easter Monday/Anzac Day"));
}

[Test]
public void Matariki()
{
var workingDayCultureInfo = new WorkingDayCultureInfo("en-NZ");

var dateOnGregorian = new DateTime(2022, 6, 24);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
dateOnGregorian = new DateTime(2023, 7, 14);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
dateOnGregorian = new DateTime(2024, 6, 28);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
dateOnGregorian = new DateTime(2025, 6, 20);
TestHoliday(workingDayCultureInfo, dateOnGregorian);
dateOnGregorian = new DateTime(2026, 7, 10);


var holidays = workingDayCultureInfo.GetHolidaysOfYear(2021);
Assert.IsFalse(holidays.Any(h => h.Name == "Matariki"));
holidays = workingDayCultureInfo.GetHolidaysOfYear(2022);
Assert.IsTrue(holidays.Any(h => h.Name == "Matariki"));
}

[Test]
public void Christmas()
{
Expand Down Expand Up @@ -105,6 +157,8 @@ public void BoxingDay()
}




private void TestHoliday(IWorkingDayCultureInfo workingDayCultureInfo, DateTime dateOnGregorian)
{
var isHoliday = workingDayCultureInfo.IsHoliday(dateOnGregorian);
Expand Down
Loading