balexandre
balexandre

Reputation: 75083

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?

Upvotes: 6

Views: 2634

Answers (5)

Ales Potocnik
Ales Potocnik

Reputation: 3087

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.

Upvotes: 7

dan04
dan04

Reputation: 91005

The DayOfWeek enumeration was designed to represent a single day of the week, not a set of days.

You don't get a compiler error for using & because enums are integers, but the operator doesn't do what you expect (unless you happen to only schedule events on Mondays, Tuesdays, or Thursdays).

If you want a bit flag, then declare a bit flag type, like Ray suggested.

Upvotes: 0

Ray
Ray

Reputation: 21905

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 };

Upvotes: 3

Albin Sunnanbo
Albin Sunnanbo

Reputation: 47038

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,
}

Upvotes: 1

Yakimych
Yakimych

Reputation: 17752

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).

Upvotes: 12

Related Questions