Skip to content

Commit

Permalink
improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiyuanliang-ms committed Nov 14, 2023
1 parent 5c823ac commit 76f2879
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ public static bool MatchRecurrence(DateTimeOffset time, TimeWindowFilterSettings
/// Try to find the closest previous recurrence occurrence before the provided time stamp according to the recurrence pattern.
/// <param name="time">A time stamp.</param>
/// <param name="settings">The settings of time window filter.</param>
/// <param name="previousOccurrence">The closest orevious occurrence.</param>
/// /// <returns>True if the closest previous occurrence is within the recurrence range, false otherwise.</returns>
/// <param name="previousOccurrence">The closest previous occurrence.</param>
/// <returns>True if the closest previous occurrence is within the recurrence range, false otherwise.</returns>
/// </summary>
private static bool TryGetPreviousOccurrence(DateTimeOffset time, TimeWindowFilterSettings settings, out DateTimeOffset previousOccurrence)
{
Expand All @@ -115,10 +115,6 @@ private static bool TryGetPreviousOccurrence(DateTimeOffset time, TimeWindowFilt

string patternType = settings.Recurrence.Pattern.Type;

RecurrenceRange range = settings.Recurrence.Range;

TimeSpan timeZoneOffset = GetRecurrenceTimeZone(settings);

int numberOfOccurrences;

if (string.Equals(patternType, Daily, StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -150,6 +146,10 @@ private static bool TryGetPreviousOccurrence(DateTimeOffset time, TimeWindowFilt
throw new ArgumentException(nameof(settings));
}

RecurrenceRange range = settings.Recurrence.Range;

TimeSpan timeZoneOffset = GetRecurrenceTimeZone(settings);

if (string.Equals(range.Type, EndDate, StringComparison.OrdinalIgnoreCase))
{
DateTime alignedPreviousOccurrence = previousOccurrence.DateTime + timeZoneOffset - previousOccurrence.Offset;
Expand All @@ -171,6 +171,13 @@ private static bool TryGetPreviousOccurrence(DateTimeOffset time, TimeWindowFilt
return true;
}

/// <summary>
/// Find the closest previous recurrence occurrence before the provided time stamp according to the "Daily" recurrence pattern.
/// <param name="time">A time stamp.</param>
/// <param name="settings">The settings of time window filter.</param>
/// <param name="previousOccurrence">The closest previous occurrence.</param>
/// <param name="numberOfOccurrences">The number of complete recurrence intervals which have occurred between the time and the recurrence start.</param>
/// </summary>
private static void FindDailyPreviousOccurrence(DateTimeOffset time, TimeWindowFilterSettings settings, out DateTimeOffset previousOccurrence, out int numberOfOccurrences)
{
RecurrencePattern pattern = settings.Recurrence.Pattern;
Expand All @@ -190,6 +197,13 @@ private static void FindDailyPreviousOccurrence(DateTimeOffset time, TimeWindowF
numberOfOccurrences = numberOfInterval;
}

/// <summary>
/// Find the closest previous recurrence occurrence before the provided time stamp according to the "Weekly" recurrence pattern.
/// <param name="time">A time stamp.</param>
/// <param name="settings">The settings of time window filter.</param>
/// <param name="previousOccurrence">The closest previous occurrence.</param>
/// <param name="numberOfOccurrences">The number of recurring days of week which have occurred between the time and the recurrence start.</param>
/// </summary>
private static void FindWeeklyPreviousOccurrence(DateTimeOffset time, TimeWindowFilterSettings settings, out DateTimeOffset previousOccurrence, out int numberOfOccurrences)
{
previousOccurrence = DateTimeOffset.MaxValue;
Expand Down Expand Up @@ -269,6 +283,13 @@ private static void FindWeeklyPreviousOccurrence(DateTimeOffset time, TimeWindow
}
}

/// <summary>
/// Find the closest previous recurrence occurrence before the provided time stamp according to the "AbsoluteMonthly" recurrence pattern.
/// <param name="time">A time stamp.</param>
/// <param name="settings">The settings of time window filter.</param>
/// <param name="previousOccurrence">The closest previous occurrence.</param>
/// <param name="numberOfOccurrences">The number of complete recurrence intervals which have occurred between the time and the recurrence start.</param>
/// </summary>
private static void FindAbsoluteMonthlyPreviousOccurrence(DateTimeOffset time, TimeWindowFilterSettings settings, out DateTimeOffset previousOccurrence, out int numberOfOccurrences)
{
RecurrencePattern pattern = settings.Recurrence.Pattern;
Expand Down Expand Up @@ -297,6 +318,13 @@ private static void FindAbsoluteMonthlyPreviousOccurrence(DateTimeOffset time, T
numberOfOccurrences = numberOfInterval;
}

/// <summary>
/// Find the closest previous recurrence occurrence before the provided time stamp according to the "RelativeMonthly" recurrence pattern.
/// <param name="time">A time stamp.</param>
/// <param name="settings">The settings of time window filter.</param>
/// <param name="previousOccurrence">The closest previous occurrence.</param>
/// <param name="numberOfOccurrences">The number of complete recurrence intervals which have occurred between the time and the recurrence start.</param>
/// </summary>
private static void FindRelativeMonthlyPreviousOccurrence(DateTimeOffset time, TimeWindowFilterSettings settings, out DateTimeOffset previousOccurrence, out int numberOfOccurrences)
{
RecurrencePattern pattern = settings.Recurrence.Pattern;
Expand Down Expand Up @@ -343,6 +371,13 @@ private static void FindRelativeMonthlyPreviousOccurrence(DateTimeOffset time, T
numberOfOccurrences = numberOfInterval;
}

/// <summary>
/// Find the closest previous recurrence occurrence before the provided time stamp according to the "AbsoluteYearly" recurrence pattern.
/// <param name="time">A time stamp.</param>
/// <param name="settings">The settings of time window filter.</param>
/// <param name="previousOccurrence">The closest previous occurrence.</param>
/// <param name="numberOfOccurrences">The number of complete recurrence intervals which have occurred between the time and the recurrence start.</param>
/// </summary>
private static void FindAbsoluteYearlyPreviousOccurrence(DateTimeOffset time, TimeWindowFilterSettings settings, out DateTimeOffset previousOccurrence, out int numberOfOccurrences)
{
RecurrencePattern pattern = settings.Recurrence.Pattern;
Expand Down Expand Up @@ -371,6 +406,13 @@ private static void FindAbsoluteYearlyPreviousOccurrence(DateTimeOffset time, Ti
numberOfOccurrences = numberOfInterval;
}

/// <summary>
/// Find the closest previous recurrence occurrence before the provided time stamp according to the "RelativeYearly" recurrence pattern.
/// <param name="time">A time stamp.</param>
/// <param name="settings">The settings of time window filter.</param>
/// <param name="previousOccurrence">The closest previous occurrence.</param>
/// <param name="numberOfOccurrences">The number of complete recurrence intervals which have occurred between the time and the recurrence start.</param>
/// </summary>
private static void FindRelativeYearlyPreviousOccurrence(DateTimeOffset time, TimeWindowFilterSettings settings, out DateTimeOffset previousOccurrence, out int numberOfOccurrences)
{
RecurrencePattern pattern = settings.Recurrence.Pattern;
Expand All @@ -389,15 +431,18 @@ private static void FindRelativeYearlyPreviousOccurrence(DateTimeOffset time, Ti

if (alignedTime.Month < alignedStart.Month)
{
//
// E.g. start: 2023.9 and time: 2024.8
// Not a complete yearly interval
yearGap -= 1;
}
else if (alignedTime.Month == alignedStart.Month)
else if (alignedTime.Month == alignedStart.Month && !pattern.DaysOfWeek.Any(day =>
alignedTime >= NthDayOfWeekInTheMonth(alignedTime, pattern.Index, day) + alignedStart.TimeOfDay))
{
if (!pattern.DaysOfWeek.Any(day =>
NthDayOfWeekInTheMonth(alignedTime, pattern.Index, day) + alignedStart.TimeOfDay <= alignedTime))
{
yearGap -= 1;
}
//
// E.g. start: 2023.9.1 (the first Friday in 2023.9) and time: 2024.9.2 (the first Friday in 2023.9 is 2024.9.6)
// Not a complete yearly interval
yearGap -= 1;
}

int numberOfInterval = yearGap / interval;
Expand Down Expand Up @@ -1278,7 +1323,7 @@ private static bool IsDurationCompliantWithDaysOfWeek(TimeSpan duration, int int
if (interval == 1)
{
//
// Check the adjacent week
// It may across weeks. Check the adjacent week
date = date.AddDays(1);

TimeSpan gap = date - prevOccurrence;
Expand All @@ -1302,10 +1347,17 @@ private static int RemainingDaysOfWeek(int day, int firstDayOfWeek)
}
else
{
return 7 - remainingDays;
return WeekDayNumber - remainingDays;
}
}

/// <summary>
/// Find the nth day of week in the month of the date time.
/// </summary>
/// <param name="dateTime">A date time.</param>
/// <param name="index">The index of the day of week in the month.</param>
/// <param name="dayOfWeek">The day of week.</param>
/// <returns>The data time of the nth day of week in the month.</returns>
private static DateTime NthDayOfWeekInTheMonth(DateTime dateTime, string index, string dayOfWeek)
{
var date = new DateTime(dateTime.Year, dateTime.Month, 1);
Expand All @@ -1317,13 +1369,15 @@ private static DateTime NthDayOfWeekInTheMonth(DateTime dateTime, string index,
date = date.AddDays(1);
}

if (date.AddDays(7 * (IndexNumber(index) - 1)).Month == dateTime.Month)
if (date.AddDays(WeekDayNumber * (IndexNumber(index) - 1)).Month == dateTime.Month)
{
date = date.AddDays(7 * (IndexNumber(index) - 1));
date = date.AddDays(WeekDayNumber * (IndexNumber(index) - 1));
}
else // There is no the 5th day of week in the month
{
date = date.AddDays(21);
//
// Add 3 weeks to reach the fourth day of week in the month
date = date.AddDays(WeekDayNumber * 3);
}

return date;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class RecurrenceRange
public int? NumberOfOccurrences { get; set; }

/// <summary>
/// Time zone for the StartDate and EndDate
/// Time zone for recurrence settings, e.g. UTC+08:00
/// </summary>
public string RecurrenceTimeZone { get; set; }
}
Expand Down

0 comments on commit 76f2879

Please sign in to comment.