views:

101

answers:

4

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?

+8  A: 

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

Yakimych
0 (Sunday) to 6 (Saturday).
Simon Svensson
I knew I was been stupid :( Thank you for pointing me out the docs ... I keep forgetting that they are an important part of the developer role... but I really did assume that DayOfWeek was a Flag Enum :o(
balexandre
+1  A: 

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,
}
Albin Sunnanbo
err... then you can't apply bit operators where in this example are the best to be used!
balexandre
Nope. But best may be from a premature optimization performance point of view, not readability point of view. List.Contains, etc are easier to read.
Albin Sunnanbo
+1  A: 

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 };
Ray
yes, I ended up doing that :) but I did assume wrongly that DayOfWeek was a Flag Enum ... Thank you.
balexandre
A: 

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.

dan04
yep... my mistake was assuming that DayofWeek was a bit flag type ... it never occur me any other way ... dumb me :-(
balexandre