Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit Flags - What am I missing?

a simple code:

protected void Page_Load(object sender, EventArgs e)
{
    DateTime now = DateTime.UtcNow;

    lit.Text += "<br/>now.DayOfWeek: " + now.DayOfWeek.ToString();

    // weekdays (Saturday is not included)
    DayOfWeek runningDays = DayOfWeek.Monday | DayOfWeek.Tuesday | DayOfWeek.Wednesday | DayOfWeek.Thursday | DayOfWeek.Friday;

    lit.Text += "<br/>" + runningDays.HasFlag(now.DayOfWeek);
    lit.Text += "<br/>" + runningDays.HasAny(now.DayOfWeek);
    lit.Text += "<br/>" + ((runningDays & now.DayOfWeek) != 0);

    // weekend (Saturday is in a weekend)
    runningDays = DayOfWeek.Saturday | DayOfWeek.Sunday;

    lit.Text += "<br/>" + runningDays.HasFlag(now.DayOfWeek);
    lit.Text += "<br/>" + runningDays.HasAny(now.DayOfWeek);
    lit.Text += "<br/>" + ((runningDays & now.DayOfWeek) != 0);
}

A helper:

public static bool HasExactly(this DayOfWeek x, DayOfWeek y) { return x == y; }
public static bool HasAny(this DayOfWeek x, DayOfWeek y) { return 0 != (x & y); }
public static bool HasAll(this DayOfWeek x, DayOfWeek y) { return y == (x & y); }

today's output (Saturday)

now.DayOfWeek: Saturday
True
True
True
True
True
True 

But the output should be like:

now.DayOfWeek: Saturday
False
False
False
True
True
True 

What am I missing here?

like image 622
balexandre Avatar asked Aug 21 '10 18:08

balexandre


4 Answers

Days of week are not bit flags. http://msdn.microsoft.com/en-us/library/system.datetime.dayofweek.aspx

The value of the constants in the DayOfWeek enumeration ranges from DayOfWeek.Sunday to DayOfWeek.Saturday. If cast to an integer, its value ranges from zero (which indicates DayOfWeek.Sunday) to six (which indicates DayOfWeek.Saturday).

like image 51
Yakimych Avatar answered Nov 08 '22 19:11

Yakimych


I know this is an old post but just in case - a neat syntax to do flags enums is

[Flags]
public enum DaysOfWeek
{
    None = 1 << 0,
    Monday = 1 << 1,
    Tuesday = 1 << 2,
    Wednesday = 1 << 3,
    Thursday = 1 << 4,
    Friday = 1 << 5,
    Saturday = 1 << 6,
    Sunday = 1 << 7
}

You would need None to indicate nothing was selected. Such an enum allows you to indicate multiple days, for example:

var selectedDays = DaysOfWeek.Tuesday | DaysOfWeek.Friday;

No comment needed hopefully. And in order to "decode" the value:

public bool IsDayOfWeekSelected(DaysOfWeek which, DaysOfWeek selection)
{
    return selection & which == which;
}

And this then allows us to call:

var isTuesday = IsDayOfWeekSelected(DaysOfWeek.Tuesday, selectedDays); // => true
var isWednesday = IsDayOfWeekSelected(DaysOfWeek.Wednesday, selectedDays); // => false
var isFriday = IsDayOfWeekSelected(DaysOfWeek.Friday, selectedDays); // => true

Hope this helps someone.

like image 21
Ales Potocnik Hahonina Avatar answered Nov 08 '22 21:11

Ales Potocnik Hahonina


You could create your own DayOfWeek enum if you need to use it like flags:

[Flags]
public enum MyDayOfWeek { Sunday = 1, Monday = 2, Tuesday = 4, ... , Saturday = 64 };
like image 3
Ray Avatar answered Nov 08 '22 19:11

Ray


DayOfWeek has sequential numbers.

Use a List<DayOfWeek>.

Go to definition shows:

// Summary:
//     Specifies the day of the week.
[Serializable]
[ComVisible(true)]
public enum DayOfWeek
{
    // Summary:
    //     Indicates Sunday.
    Sunday = 0,
    //
    // Summary:
    //     Indicates Monday.
    Monday = 1,
    //
    // Summary:
    //     Indicates Tuesday.
    Tuesday = 2,
    //
    // Summary:
    //     Indicates Wednesday.
    Wednesday = 3,
    //
    // Summary:
    //     Indicates Thursday.
    Thursday = 4,
    //
    // Summary:
    //     Indicates Friday.
    Friday = 5,
    //
    // Summary:
    //     Indicates Saturday.
    Saturday = 6,
}
like image 1
Albin Sunnanbo Avatar answered Nov 08 '22 21:11

Albin Sunnanbo