public void GetNextDayOfMonth ( DateTime after, int dayOfMonth, UnrepresentableDateHandling unrepresentableDateHandling, DateTime?[] expected ) { var result = DayOfMonthTrigger .GetNextDayOfMonth(after, dayOfMonth, unrepresentableDateHandling)? .ToArray(); Assert.IsNotNull(result); Assert.AreEqual(expected.Length, result.Length); for (var i = 0; i < result.Length; i++) { Assert.AreEqual(expected[i], result[i]); } }
/// <summary> /// Helper method to return the next potential run date within a schedule. /// </summary> /// <param name="after">The day to start looking on.</param> /// <param name="dayOfMonth">The day of the month to return.</param> /// <returns> /// If <paramref name="after"/> is the same day as <paramref name="dayOfWeek"/> then will return /// two items - one for today and one for the same day month. /// If not then it will return one item - for the next time that this day occurs /// (later this month or next, depending on parameters). /// </returns> internal static IEnumerable <DateTime> GetNextDayOfMonth ( DateTime after, int dayOfMonth, UnrepresentableDateHandling unrepresentableDateHandling ) { // If the day of the month is invalid then return no values. if (dayOfMonth < 1 || dayOfMonth > 32) { yield break; } // Switch logic depending on the current day. if (dayOfMonth == after.Day) { // It's today. // We could be running today or the same day next month (depending on trigger times). // Return both options. yield return(after.Date); yield return (new DateTime(after.Year, after.Month, 1) .AddMonths(1) // One month .AddDays(dayOfMonth - 1)); // Move forward to the correct day. } else if (dayOfMonth < after.Day) { // This day has already passed. // Return the correct day next month. yield return(new DateTime(after.Year, after.Month, dayOfMonth).AddMonths(1)); } else { // Day is in the future this month. var sanity = 0; var month = after.Month; while (sanity++ < 6) { DateTime?date = null; try { // Can we represent this date? // If not then we've asked for 30th Feb or similar. date = new DateTime(after.Year, month, dayOfMonth); } catch { // What should we do? switch (unrepresentableDateHandling) { case UnrepresentableDateHandling.LastDayOfMonth: // Get the last day of this month instead. date = new DateTime(after.Year, month, 1) .AddMonths(1) .AddDays(-1); break; default: // Allow it to try the next month. date = null; month++; break; } } // If we can represent it then return it, otherwise move to next month. if (date.HasValue) { yield return(date.Value); break; } } } }