diff --git a/PH.WorkingDaysAndTime/Directory.Build.props b/PH.WorkingDaysAndTime/Directory.Build.props index e7000c9..12edab8 100644 --- a/PH.WorkingDaysAndTime/Directory.Build.props +++ b/PH.WorkingDaysAndTime/Directory.Build.props @@ -2,9 +2,9 @@ Paolo Innocenti Copyright 2021 (c) Paolo Innocenti - paonath@gmail.com - 2.0.8 - 2.0.8 - 2.0.8 + 2.0.9 + 2.0.9 + 2.0.9 diff --git a/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility.UnitTest/MultiCalculatedHolidaysTest.cs b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility.UnitTest/MultiCalculatedHolidaysTest.cs new file mode 100644 index 0000000..075a796 --- /dev/null +++ b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility.UnitTest/MultiCalculatedHolidaysTest.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using PH.WorkingDaysAndTimeUtility.Configuration; +using Xunit; + +namespace PH.WorkingDaysAndTimeUtility.UnitTest +{ + public class MultiCalculatedHolidaysTest : BaseTest + { + [Fact] + public void TestWorkingOnSaturdayIfOdd() + { + var wts1 = new WorkTimeSpan() { Start = new TimeSpan(9, 0, 0), End = new TimeSpan(13, 0, 0) }; + + var wts2 = new WorkTimeSpan() { Start = new TimeSpan(14, 0, 0), End = new TimeSpan(18, 0, 0) }; + var wts = new List() { wts1, wts2 }; + var week = new WeekDaySpan() + { + WorkDays = new Dictionary() + { + {DayOfWeek.Monday, new WorkDaySpan() {TimeSpans = wts }} + , + {DayOfWeek.Tuesday, new WorkDaySpan() {TimeSpans = wts}} + , + {DayOfWeek.Wednesday, new WorkDaySpan() {TimeSpans = wts}} + , + {DayOfWeek.Thursday, new WorkDaySpan() {TimeSpans = wts}} + , + {DayOfWeek.Friday, new WorkDaySpan() {TimeSpans = wts}} , + {DayOfWeek.Saturday, new WorkDaySpan() {TimeSpans = wts}} + } + }; + + var italians = GetItalianHolidaysWithNoEasterMonday(); + italians.Add(new EasterMonday()); + italians.Add(new HoliDay(1, 12)); + italians.Add(new WorkingOnSaturdayIfOdd()); + + var utility = new PH.WorkingDaysAndTimeUtility.WorkingDaysAndTimeUtility(week, italians); + + var aSaturday = new DateTime(2021, 8, 7); + var t1 = utility.IsAWorkDay(aSaturday); + var t2 = utility.IsAWorkDay(aSaturday.AddDays(7)); + var t3 = utility.IsAWorkDay(aSaturday.AddDays(14)); + var t4 = utility.IsAWorkDay(aSaturday.AddDays(21)); + + Assert.False(t1); + Assert.False(t3); + Assert.True(t2); + Assert.True(t4); + + } + } + + public class WorkingOnSaturdayIfOdd : MultiCalculatedHoliDay + { + public WorkingOnSaturdayIfOdd() : base(0, 0) + { + } + + public override Type GetHolyDayType() => typeof(WorkingOnSaturdayIfOdd); + + /// Calculates the list of MultiCalculatedHoliDays for the given year. + /// The year. + /// + public override List CalculateList(int year) + { + var first = new DateTime(year, 1, 1, 0, 0, 0); + var last = new DateTime(year +1, 1, 1, 0, 0, 0); + CultureInfo myCI = new CultureInfo("it-IT"); + var baseHolidays = new List(); + while (first < last) + { + if (first.DayOfWeek == DayOfWeek.Saturday) + { + var weekNumber = myCI.Calendar.GetWeekOfYear(first, CalendarWeekRule.FirstDay, DayOfWeek.Monday); + if (weekNumber % 2 == 0) + { + baseHolidays.Add(first); + } + } + + first = first.AddDays(1); + } + + return baseHolidays; + } + } +} \ No newline at end of file diff --git a/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/Configuration/HoliDay.cs b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/Configuration/HoliDay.cs index 1be230c..b68dd04 100644 --- a/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/Configuration/HoliDay.cs +++ b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/Configuration/HoliDay.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Newtonsoft.Json; using PH.WorkingDaysAndTimeUtility.Converter; @@ -150,6 +151,33 @@ public string AHolyDayToString() } } + public abstract class MultiCalculatedHoliDay : CalculatedHoliDay + { + + /// + /// It returns an instance of the data by year provided + /// + /// year provided + /// DateTime + [Obsolete("For MultiCalculatedHoliDay use 'List CalculateList(int year);'", true)] +#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member + public override DateTime Calculate(int year) +#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member + { + throw new + NotSupportedException($"For {nameof(MultiCalculatedHoliDay)} use 'List CalculateList(int year);'"); + } + + /// Calculates the list of MultiCalculatedHoliDays for the given year. + /// The year. + /// + public abstract List CalculateList(int year); + + protected MultiCalculatedHoliDay(int day, int mont) : base(day, mont) + { + } + } + /// /// Holiday: a non-working day. /// diff --git a/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/PH.WorkingDaysAndTimeUtility.csproj b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/PH.WorkingDaysAndTimeUtility.csproj index 98e57fc..9bd0ec5 100644 --- a/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/PH.WorkingDaysAndTimeUtility.csproj +++ b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/PH.WorkingDaysAndTimeUtility.csproj @@ -15,14 +15,13 @@ The application works only counting the dates forward and it is assumed that the date entered as the first parameter is a working day. - Fix time splitting bugs. - Now able to determine if given date is holyday + Now able to add multi-calculated holidays to your configuration - work-days,DateTime,work-hours,work-minutes,work-DateTime,holiday,timespan, time-slices + work-days,DateTime,work-hours,work-minutes,work-DateTime,holiday,timespan, time-slices, holiday - 2.0.8 + 2.0.9 Paolo Innocenti Copyright PH 2021 (c) paonath@gmail.com. All rights reserved. https://github.com/paonath/PH.WorkingDaysAndTime diff --git a/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/WorkingDaysAndTimeUtility.cs b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/WorkingDaysAndTimeUtility.cs index 0e9b3cf..5f41634 100644 --- a/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/WorkingDaysAndTimeUtility.cs +++ b/PH.WorkingDaysAndTime/PH.WorkingDaysAndTimeUtility/WorkingDaysAndTimeUtility.cs @@ -898,7 +898,15 @@ private List CalculateDaysForExclusions(int year) { try { - r.Add(day.Calculate(year)); + if (day is MultiCalculatedHoliDay multi) + { + r.AddRange(multi.CalculateList(year)); + } + else + { + r.Add(day.Calculate(year)); + } + } catch { diff --git a/README.md b/README.md index 2ec920f..142c311 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,89 @@ var res = utility.SplitWorkedTimeInFactors(n, e); var hours = res.TotalDuration.TotalHours; ``` +**Implements a multi-calculated holiday** +```c# +public class WorkingOnSaturdayIfOdd : MultiCalculatedHoliDay + { + public WorkingOnSaturdayIfOdd() : base(0, 0) + { + } + + public override Type GetHolyDayType() => typeof(WorkingOnSaturdayIfOdd); + + /// Calculates the list of MultiCalculatedHoliDays for the given year. + /// The year. + /// + public override List CalculateList(int year) + { + var first = new DateTime(year, 1, 1, 0, 0, 0); + var last = new DateTime(year +1, 1, 1, 0, 0, 0); + CultureInfo myCI = new CultureInfo("it-IT"); + var baseHolidays = new List(); + while (first < last) + { + if (first.DayOfWeek == DayOfWeek.Saturday) + { + var weekNumber = myCI.Calendar.GetWeekOfYear(first, CalendarWeekRule.FirstDay, DayOfWeek.Monday); + if (weekNumber % 2 == 0) + { + baseHolidays.Add(first); + } + } + + first = first.AddDays(1); + } + + return baseHolidays; + } + } +//... +[Fact] + public void TestWorkingOnSaturdayIfOdd() + { + var wts1 = new WorkTimeSpan() { Start = new TimeSpan(9, 0, 0), End = new TimeSpan(13, 0, 0) }; + + var wts2 = new WorkTimeSpan() { Start = new TimeSpan(14, 0, 0), End = new TimeSpan(18, 0, 0) }; + var wts = new List() { wts1, wts2 }; + var week = new WeekDaySpan() + { + WorkDays = new Dictionary() + { + {DayOfWeek.Monday, new WorkDaySpan() {TimeSpans = wts }} + , + {DayOfWeek.Tuesday, new WorkDaySpan() {TimeSpans = wts}} + , + {DayOfWeek.Wednesday, new WorkDaySpan() {TimeSpans = wts}} + , + {DayOfWeek.Thursday, new WorkDaySpan() {TimeSpans = wts}} + , + {DayOfWeek.Friday, new WorkDaySpan() {TimeSpans = wts}} , + {DayOfWeek.Saturday, new WorkDaySpan() {TimeSpans = wts}} + } + }; + + var italians = GetItalianHolidaysWithNoEasterMonday(); + italians.Add(new EasterMonday()); + italians.Add(new HoliDay(1, 12)); + italians.Add(new WorkingOnSaturdayIfOdd()); + + var utility = new PH.WorkingDaysAndTimeUtility.WorkingDaysAndTimeUtility(week, italians); + + var aSaturday = new DateTime(2021, 8, 7); + var t1 = utility.IsAWorkDay(aSaturday); + var t2 = utility.IsAWorkDay(aSaturday.AddDays(7)); + var t3 = utility.IsAWorkDay(aSaturday.AddDays(14)); + var t4 = utility.IsAWorkDay(aSaturday.AddDays(21)); + + Assert.False(t1); + Assert.False(t3); + Assert.True(t2); + Assert.True(t4); + + } + } +``` + ## Code Configuration Examples **Use of WorkingDaysConfig**