@@ -49,10 +49,17 @@ static class RecurrenceEvaluator
4949 const string Numbered = "Numbered" ;
5050 const string NoEnd = "NoEnd" ;
5151
52- const int WeeklyUnitIntervalDuration = 7 ; // in days
53- const int MonthlyUnitIntervalDuration = 28 ; // in days
54- const int YearlyUnitIntervalDuration = 365 ; // in days
55-
52+ const int WeekDayNumber = 7 ;
53+ const int MinMonthDayNumber = 28 ;
54+ const int MinYearDayNumber = 365 ;
55+
56+ /// <summary>
57+ /// Checks if a provided timestamp is within any recurring time window specified by the Recurrence section in the time window filter settings.
58+ /// If the time window filter has an invalid recurrence setting, an exception will be thrown.
59+ /// <param name="time">A time stamp.</param>
60+ /// <param name="settings">The settings of time window filter.</param>
61+ /// <returns>True if the time stamp is within any recurring time window, false otherwise.</returns>
62+ /// </summary>
5663 public static bool MatchRecurrence ( DateTimeOffset time , TimeWindowFilterSettings settings )
5764 {
5865 if ( settings == null )
@@ -88,6 +95,13 @@ public static bool MatchRecurrence(DateTimeOffset time, TimeWindowFilterSettings
8895 return false ;
8996 }
9097
98+ /// <summary>
99+ /// Try to find the closest previous recurrence occurrence before the provided time stamp according to the recurrence pattern.
100+ /// <param name="time">A time stamp.</param>
101+ /// <param name="settings">The settings of time window filter.</param>
102+ /// <param name="previousOccurrence">The closest orevious occurrence.</param>
103+ /// /// <returns>True if the closest previous occurrence is within the recurrence range, false otherwise.</returns>
104+ /// </summary>
91105 private static bool TryGetPreviousOccurrence ( DateTimeOffset time , TimeWindowFilterSettings settings , out DateTimeOffset previousOccurrence )
92106 {
93107 previousOccurrence = DateTimeOffset . MaxValue ;
@@ -619,13 +633,13 @@ private static bool TryValidateWeeklyRecurrencePattern(TimeWindowFilterSettings
619633
620634 RecurrencePattern pattern = settings . Recurrence . Pattern ;
621635
622- TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * WeeklyUnitIntervalDuration ) ;
636+ TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * WeekDayNumber ) ;
623637
624638 TimeSpan timeWindowDuration = settings . End . Value - settings . Start . Value ;
625639
626640 //
627641 // Time window duration must be shorter than how frequently it occurs
628- if ( settings . End . Value - settings . Start . Value > intervalDuration )
642+ if ( timeWindowDuration > intervalDuration )
629643 {
630644 paramName = $ "{ nameof ( settings . End ) } ";
631645
@@ -684,7 +698,7 @@ private static bool TryValidateAbsoluteMonthlyRecurrencePattern(TimeWindowFilter
684698
685699 RecurrencePattern pattern = settings . Recurrence . Pattern ;
686700
687- TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * MonthlyUnitIntervalDuration ) ;
701+ TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * MinMonthDayNumber ) ;
688702
689703 //
690704 // Time window duration must be shorter than how frequently it occurs
@@ -730,7 +744,7 @@ private static bool TryValidateRelativeMonthlyRecurrencePattern(TimeWindowFilter
730744
731745 RecurrencePattern pattern = settings . Recurrence . Pattern ;
732746
733- TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * MonthlyUnitIntervalDuration ) ;
747+ TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * MinMonthDayNumber ) ;
734748
735749 //
736750 // Time window duration must be shorter than how frequently it occurs
@@ -782,7 +796,7 @@ private static bool TryValidateAbsoluteYearlyRecurrencePattern(TimeWindowFilterS
782796
783797 RecurrencePattern pattern = settings . Recurrence . Pattern ;
784798
785- TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * YearlyUnitIntervalDuration ) ;
799+ TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * MinYearDayNumber ) ;
786800
787801 //
788802 // Time window duration must be shorter than how frequently it occurs
@@ -833,7 +847,7 @@ private static bool TryValidateRelativeYearlyRecurrencePattern(TimeWindowFilterS
833847
834848 RecurrencePattern pattern = settings . Recurrence . Pattern ;
835849
836- TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * YearlyUnitIntervalDuration ) ;
850+ TimeSpan intervalDuration = TimeSpan . FromDays ( pattern . Interval * MinYearDayNumber ) ;
837851
838852 //
839853 // Time window duration must be shorter than how frequently it occurs
@@ -1211,9 +1225,17 @@ private static TimeSpan GetRecurrenceTimeZone(TimeWindowFilterSettings settings)
12111225 return timeZoneOffset ;
12121226 }
12131227
1228+ /// <summary>
1229+ /// Check whether the duration is shorter than the minimum gap between recurrence of days of week.
1230+ /// </summary>
1231+ /// <param name="duration">The time span of the duration.</param>
1232+ /// <param name="interval">The recurrence interval.</param>
1233+ /// <param name="daysOfWeek">The days of the week when the recurrence will occur.</param>
1234+ /// <param name="firstDayOfWeek">The first day of the week.</param>
1235+ /// <returns>True if the duration is compliant with days of week, false otherwise.</returns>
12141236 private static bool IsDurationCompliantWithDaysOfWeek ( TimeSpan duration , int interval , IEnumerable < string > daysOfWeek , string firstDayOfWeek )
12151237 {
1216- if ( daysOfWeek == null || daysOfWeek . Count ( ) < 1 )
1238+ if ( daysOfWeek == null || ! daysOfWeek . Any ( ) )
12171239 {
12181240 throw new ArgumentException ( nameof ( daysOfWeek ) ) ;
12191241 }
0 commit comments