I thought I'd share this bit of code with you. It's basically a way of converting the System.DayOfWeek enum
into a bitfield enum
. Because I'm working on a transit database, I need a column that lets me store specific combinations of days, like Monday to Friday, or Saturday and Sunday. I'd like to translate those combinations into int
s and back into combinations. So here's the utility class to do it:
public static class DaysOfWeekUtils
{
#region Nested Enums
[Flags]
private enum DayOfWeekBitFlag
{
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x10,
Friday = 0x20,
Saturday = 0x40
}
#endregion
#region Private Fields
private static Dictionary<DayOfWeekBitFlag, DayOfWeek> systemDayOfWeek;
private static Dictionary<DayOfWeek, DayOfWeekBitFlag> bitFlagDayOfWeek;
#endregion
#region Constructors
static DaysOfWeekUtils()
{
systemDayOfWeek = new Dictionary<DayOfWeekBitFlag, DayOfWeek>();
systemDayOfWeek[DayOfWeekBitFlag.Sunday] = DayOfWeek.Sunday;
systemDayOfWeek[DayOfWeekBitFlag.Monday] = DayOfWeek.Monday;
systemDayOfWeek[DayOfWeekBitFlag.Tuesday] = DayOfWeek.Tuesday;
systemDayOfWeek[DayOfWeekBitFlag.Wednesday] = DayOfWeek.Wednesday;
systemDayOfWeek[DayOfWeekBitFlag.Thursday] = DayOfWeek.Thursday;
systemDayOfWeek[DayOfWeekBitFlag.Friday] = DayOfWeek.Friday;
systemDayOfWeek[DayOfWeekBitFlag.Saturday] = DayOfWeek.Saturday;
bitFlagDayOfWeek = new Dictionary<DayOfWeek, DayOfWeekBitFlag>();
bitFlagDayOfWeek[DayOfWeek.Sunday] = DayOfWeekBitFlag.Sunday;
bitFlagDayOfWeek[DayOfWeek.Monday] = DayOfWeekBitFlag.Monday;
bitFlagDayOfWeek[DayOfWeek.Tuesday] = DayOfWeekBitFlag.Tuesday;
bitFlagDayOfWeek[DayOfWeek.Wednesday] = DayOfWeekBitFlag.Wednesday;
bitFlagDayOfWeek[DayOfWeek.Thursday] = DayOfWeekBitFlag.Thursday;
bitFlagDayOfWeek[DayOfWeek.Friday] = DayOfWeekBitFlag.Friday;
bitFlagDayOfWeek[DayOfWeek.Saturday] = DayOfWeekBitFlag.Saturday;
MondayToFridayCode = valueOf(DayOfWeek.Monday, DayOfWeek.Tuesday,
DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday);
}
#endregion
#region Public Properties
public static int MondayToFridayCode { get; private set; }
public static IEnumerable<DayOfWeek> EachDayOfTheWeek
{
get
{
yield return DayOfWeek.Sunday;
yield return DayOfWeek.Monday;
yield return DayOfWeek.Tuesday;
yield return DayOfWeek.Wednesday;
yield return DayOfWeek.Thursday;
yield return DayOfWeek.Friday;
yield return DayOfWeek.Saturday;
}
}
public static IEnumerable<DayOfWeek> MondayToFriday
{
get
{
return daysOfWeek(MondayToFridayCode);
}
}
#endregion
#region Public Methods
public static IEnumerable<DayOfWeek> daysOfWeek(int val)
{
foreach (DayOfWeekBitFlag bitFlag in systemDayOfWeek.Keys)
if ((val & (int)bitFlag) == (int)bitFlag)
yield return systemDayOfWeek[bitFlag];
}
public static int valueOf(params DayOfWeek[] daysOfWeek)
{
return daysOfWeek.Distinct().Sum(dayOfWeek => (int)bitFlagDayOfWeek[dayOfWeek]);
}
#endregion
}
and here is its test class:
[TestClass]
public class DayOfWeekUtilsUnitTests
{
#region Test Methods
[TestMethod]
public void testDaysOfTheWeek()
{
foreach (DayOfWeek[] combination in combinations(7))
testDaysOfWeek(combination);
foreach (DayOfWeek[] combination in combinations(6))
testDaysOfWeek(combination);
foreach (DayOfWeek[] combination in combinations(5))
testDaysOfWeek(combination);
foreach (DayOfWeek[] combination in combinations(4))
testDaysOfWeek(combination);
foreach (DayOfWeek[] combination in combinations(3))
testDaysOfWeek(combination);
foreach (DayOfWeek[] combination in combinations(2))
testDaysOfWeek(combination);
foreach (DayOfWeek[] combination in combinations(1))
testDaysOfWeek(combination);
}
private IEnumerable<DayOfWeek[]> combinations(int arrayLength)
{
if (arrayLength == 0)
yield return new DayOfWeek[0];
else
foreach (DayOfWeek dayOfWeek in DaysOfWeekUtils.EachDayOfTheWeek)
foreach (DayOfWeek[] combination in combinations(arrayLength - 1))
yield return combination.Concat(Enumerable.Repeat(dayOfWeek, 1)).ToArray();
}
[TestMethod]
public void testDaysOfTheWeekUtilsProperty()
{
IEnumerable<DayOfWeek> daysOfTheWeek = DaysOfWeekUtils.EachDayOfTheWeek;
Assert.AreEqual(daysOfTheWeek.Count(), 7);
Assert.IsTrue(daysOfTheWeek.Contains(DayOfWeek.Sunday));
Assert.IsTrue(daysOfTheWeek.Contains(DayOfWeek.Monday));
Assert.IsTrue(daysOfTheWeek.Contains(DayOfWeek.Tuesday));
Assert.IsTrue(daysOfTheWeek.Contains(DayOfWeek.Wednesday));
Assert.IsTrue(daysOfTheWeek.Contains(DayOfWeek.Thursday));
Assert.IsTrue(daysOfTheWeek.Contains(DayOfWeek.Friday));
Assert.IsTrue(daysOfTheWeek.Contains(DayOfWeek.Saturday));
}
[TestMethod]
public void testMondayToFriday()
{
IEnumerable<DayOfWeek> mondayToFriday = DaysOfWeekUtils.MondayToFriday;
Assert.IsTrue(mondayToFriday.Count() == 5);
Assert.IsTrue(mondayToFriday.Contains(DayOfWeek.Monday));
Assert.IsTrue(mondayToFriday.Contains(DayOfWeek.Tuesday));
Assert.IsTrue(mondayToFriday.Contains(DayOfWeek.Wednesday));
Assert.IsTrue(mondayToFriday.Contains(DayOfWeek.Thursday));
Assert.IsTrue(mondayToFriday.Contains(DayOfWeek.Friday));
}
[TestMethod]
public void testNonExistentDays()
{
IEnumerable<DayOfWeek> noDays = DaysOfWeekUtils.daysOfWeek(256);
Assert.AreEqual(noDays.Count(), 0);
}
#endregion
#region Private Methods
private void testDaysOfWeek(params DayOfWeek[] daysOfWeek)
{
int val = DaysOfWeekUtils.valueOf(daysOfWeek);
IEnumerable<DayOfWeek> computedEnumeration = DaysOfWeekUtils.daysOfWeek(val);
Assert.AreEqual(daysOfWeek.Distinct().Count(), computedEnumeration.Count());
foreach (DayOfWeek dayOfWeek in computedEnumeration)
Assert.IsTrue(daysOfWeek.Contains(dayOfWeek));
}
#endregion
}
To convert an int
into an IEnumerable<DayOfWeek>
, use the daysOfWeek()
method; to go the other way, use the valueOf()
method. I've included ModayToFriday
and ModayToFridayCode
shortcuts; feel free to add your own as and when the need arises.
Enjoy!
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.