In C#, given an arbitrary set of DayOfWeek end points (like, DayOfWeek.Friday and DayOfWeek.Sunday) how would one test if an arbitrary date falls between those two days, inclusive?
Example:
// result == true; Oct 23, 2010 is a Saturday
var result = InBetweenDaysInclusive(new DateTime(2010, 10, 23),
DayOfWeek.Friday,
DayOfWeek.Sunday);
// result == true; Oct 22, 2010 is a Friday
result = InBetweenDaysInclusive(new DateTime(2010, 10, 22),
DayOfWeek.Friday,
DayOfWeek.Sunday);
// result == true; Oct 24, 2010 is a Sunday
result = InBetweenDaysInclusive(new DateTime(2010, 10, 24),
DayOfWeek.Friday,
DayOfWeek.Sunday);
// result == false; Oct 25, 2010 is a Monday
result = InBetweenDaysInclusive(new DateTime(2010, 10, 25),
DayOfWeek.Friday,
DayOfWeek.Sunday);
Thanks!
This function is going to need two separate branches depending on whether the difference between start and end date is negative or positive/zero.
I could be totally off-base, but I think this works for all cases:
// No state in method, so made it static
public static bool InBetweenDaysInclusive(DateTime date, DayOfWeek start, DayOfWeek end)
{
DayOfWeek curDay = date.DayOfWeek;
if (start <= end)
{
// Test one range: start to end
return (start <= curDay && curDay <= end);
}
else
{
// Test two ranges: start to 6, 0 to end
return (start <= curDay || curDay <= end);
}
}
For reference, your test data returned the following when I ran it and added Console.WriteLine for each result:
True
True
True
False
Edit: My last explanation was too vague. Here's a fixed one.
The trick is that if end < start
, then you have two valid ranges: start
to upper bound and lower bound to end
. This would result in (start <= curDay && curDay <= upperBound) || curDay <= end && lowerBound <= curDay)
However, since they are bounds, curDay
is always <= upperBound
and >= lowerBound
, thus we omit that code.
Every date falls between any two given days of the week (think about it)...
You would need to get the endpoint dates for the dayOfWeek closest to the date in question (where day difference < 7). Then, you do a simple comparison.
NOTE: the following solution assumes a week is Sunday to Saturday
Given the following extension methods:
/// <summary>
/// Gets the date of the next occurrence of the day of week provided
/// </summary>
/// <param name="value"></param>
/// <param name="nextDay"></param>
/// <returns></returns>
public static DateTime NextOccurance(this DateTime value, DayOfWeek nextDay)
{
if (value.DayOfWeek == nextDay) { return value; }
else if (value.DayOfWeek > nextDay) { return value.AddDays(7 - (value.DayOfWeek - nextDay)); }
else { return value.AddDays(nextDay - value.DayOfWeek); }
}
/// <summary>
/// Gets the date of the last occurrence of the day of week provided
/// </summary>
/// <param name="value"></param>
/// <param name="lastDay"></param>
/// <returns></returns>
public static DateTime LastOccurance(this DateTime value, DayOfWeek lastDay)
{
if (value.DayOfWeek == lastDay) { return value; }
else if (value.DayOfWeek > lastDay) { return value.AddDays(-(value.DayOfWeek - lastDay)); }
else { return value.AddDays((lastDay - value.DayOfWeek) - 7); }
}
/// <summary>
/// Gets the date of the closest occurrence of the day of week provided
/// </summary>
/// <param name="value"></param>
/// <param name="day"></param>
/// <returns></returns>
public static DateTime ClosestOccurance(this DateTime value, DayOfWeek day)
{
DateTime before = value.LastOccurance(day);
DateTime after = value.NextOccurance(day);
return ((value - before) < (after - value))
? before
: after;
}
You can find out if the dayOfWeek in question falls within two dates like this: (this is the part that assumes a week is Sunday to Saturday)
DayOfWeek dayOne = DayOfWeek.Tuesday;
DayOfWeek dayTwo = DayOfWeek.Friday;
DateTime doesDateFallWithin = DateTime.Today;
bool fallsWithin =
doesDateFallWithin.ClosestOccurance(dayOne) <= doesDateFallWithin
&& doesDateFallWithin <= doesDateFallWithin.ClosestOccurance(dayTwo);
dayOne = Friday, dayTwo = Tuesday
10/27/2010 (Wednesday) does not fall within the closest occurrences of Friday (10/29/2010) and Tuesday (10/26/2010)
10/28/2010 (Thursday) does not fall within the closest occurrences of Friday (10/29/2010) and Tuesday (10/26/2010)
10/29/2010 (Friday) does not fall within the closest occurrences of Friday (10/29/2010) and Tuesday (10/26/2010)
10/30/2010 (Saturday) falls within the closest occurrences of Friday (10/29/2010) and Tuesday (11/2/2010)
10/31/2010 (Sunday) falls within the closest occurrences of Friday (10/29/2010) and Tuesday (11/2/2010)
11/1/2010 (Monday) falls within the closest occurrences of Friday (10/29/2010) and Tuesday (11/2/2010)
11/2/2010 (Tuesday) does not fall within the closest occurrences of Friday (11/5/2010) and Tuesday (11/2/2010)
11/3/2010 (Wednesday) does not fall within the closest occurrences of Friday (11/5/2010) and Tuesday (11/2/2010)
dayOne = Monday, dayTwo = Wednesday
10/27/2010 (Wednesday) falls within the closest occurrences of Monday (10/25/2010) and Wednesday (10/27/2010)
10/28/2010 (Thursday) does not fall within the closest occurrences of Monday (10/25/2010) and Wednesday (10/27/2010)
10/29/2010 (Friday) does not fall within the closest occurrences of Monday (11/1/2010) and Wednesday (10/27/2010)
10/30/2010 (Saturday) does not fall within the closest occurrences of Monday (11/1/2010) and Wednesday (10/27/2010)
10/31/2010 (Sunday) does not fall within the closest occurrences of Monday (11/1/2010) and Wednesday (11/3/2010)
11/1/2010 (Monday) falls within the closest occurrences of Monday (11/1/2010) and Wednesday (11/3/2010)
11/2/2010 (Tuesday) falls within the closest occurrences of Monday (11/1/2010) and Wednesday (11/3/2010)
11/3/2010 (Wednesday) falls within the closest occurrences of Monday (11/1/2010) and Wednesday (11/3/2010)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With