2

I have my own DaysOfWeek Flag enum (kind of https://learn.microsoft.com/en-us/previous-versions/ms886541(v=msdn.10))

[Flags]
public enum DayOfWeek
{
    Sunday = 0,
    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32
}

And I need to compare standard DayOfWeek with mine. How can I do that?

kenazs
  • 71
  • 10
  • It'd be helpful if you'd define "compare" and what you want the results to be. Will this comparison return `bool` or `int`? When comparing your `DayOfWeek` to a `System.DayOfWeek` is it strictly testing for equality, or given a `System.DayOfWeek` that the corresponding flag is set in your `DayOfWeek`, regardless of the state of the other flags? Also, what have you tried? – Lance U. Matthews Jun 23 '19 at 06:19
  • 6
    Side note, but are you sure about `Sunday = 0` ? It will be hard to include or exclude Sunday from a set. – H H Jun 23 '19 at 06:23
  • @BACON I have own enum to create combinations of days and I need to define is that DateTime.Now in this combination. Want to return `bool`. – kenazs Jun 24 '19 at 01:41

4 Answers4

3

Since your enum uses the same order of days as the built-in DayOfWeek, all you need to do is to use the variable of DayOfWeek type as the exponent of 2 and then bitwise-AND it with your enum variable.

Something like this (this will check if Monday flag of your enum is 1 or not):

MyDayOfWeek Days = MyDayOfWeek.Monday | MyDayOfWeek.Friday;
DayOfWeek D = DayOfWeek.Monday;
var Mask = 1 << (int)D;

if ((Mask & (int)Days) == Mask)
  //Do whatever;

I have renamed your enum to MyDaysOfWeek, whereas DayOfWeek is the built-in .NET type. You can do the same for any day of week.

Edit

As @HenkHolterman pointed out (thanks for that), you'll have problems with your Sunday set to 0. A Flags enum should normally start with a member named None that is equal to 0 and which indicates that none of the flags of the variable are set.

dotNET
  • 33,414
  • 24
  • 162
  • 251
  • For computing powers of 2 in C#, you want to use `1 << N` not `2 ^ N`. The latter is XOR. – Ben Voigt Jun 23 '19 at 05:59
  • Also, the bitwise AND is not necessary. Left-shifting `1` will create a number with only one bit set. – Ben Voigt Jun 23 '19 at 06:00
  • @BenVoigt: Working in two languages can be messy. That one came from Visual Basic. Thanks for the correction. Updated. – dotNET Jun 23 '19 at 06:01
  • @BenVoigt: Can u please suggest how can ANDing be avoided? His enum is marked `Flags` and can have multiple bits set. – dotNET Jun 23 '19 at 06:09
  • @dotNET mb using HasFlag? Its available since .net 4 – kenazs Jun 23 '19 at 06:17
  • 1
    Did you test this with `MyDayOfWeek.Sunday` ? – H H Jun 23 '19 at 06:24
  • @kenazs: Thanks for the fiddle. And yes, `HasFlag` is an option. Though personally I'd prefer a simple intrinsic operator over a function call. – dotNET Jun 23 '19 at 07:02
  • @dotNET: Ah, now I understand you're testing for membership in a set -- yes you are correct the AND is necessary for that. I thought OP was looking for an equality test. – Ben Voigt Jun 23 '19 at 15:48
2

Thanks everyone for help. Finally, I have solution

Own DaysOfWeek with flag:

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

Since own enum has same order of days, we can write extension method to convert standard DayOfWeek to own

public static class EnumExtensions
{
    public static DaysOfWeek ToFlag(this DayOfWeek dayOfWeek)
    {
        var mask = 1 << (int)dayOfWeek;
        return (DaysOfWeek)Enum.ToObject(typeof(DaysOfWeek), mask);
    }
}

And usage:

  var days = DaysOfWeek.Sunday | DaysOfWeek.Friday;
  var day = DayOfWeek.Sunday;
  var ownDay = day.ToFlag();
  if (days.HasFlag(ownDay))
      // Do whatever;

playground: https://dotnetfiddle.net/sV3yge

kenazs
  • 71
  • 10
0
public enum BitwiseDayOfWeek
{
    Sunday   = 1,
    Monday   = 2,
    Tuesday  = 4,
    Wednesday    = 8,
    Thursday     = 16,
    Friday   = 32,
    Saturday     = 64
}

public class Program
{
    public static void Main(string[] args)
    {
        BitwiseDayOfWeek scheduledDayOfWeek
            = BitwiseDayOfWeek.Saturday | BitwiseDayOfWeek.Sunday;

        // turn System.DayOfWeek (DateTime.Now.DayOfWeek) into BitwiseDayOfWeek
        BitwiseDayOfWeek currentDayOfWeek
            = (BitwiseDayOfWeek)Math.Pow(2, (double)DateTime.Now.DayOfWeek);

        // test if today is the scheduled day
        if ( (currentDayOfWeek & scheduledDayOfWeek) == currentDayOfWeek )
            Console.WriteLine(currentDayOfWeek);

        Console.WriteLine("---------------------");
        Console.ReadLine();
    }
}
-3

If you change your Enum like this:

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

You can try this:

class Program
{
    public static bool Equal(DayOfWeek mine, System.DayOfWeek cSharp)
    {
        int mineInt = (int)mine;
        int cSharpInt = (int)cSharp;
        return mineInt == cSharpInt;
    }

    static void Main(string[] args)
    {

        DateTime dateTime = DateTime.Now;
        DayOfWeek dayOfWeek = DayOfWeek.Sunday;

        bool areEqual = Equal(dayOfWeek, dateTime.DayOfWeek);
        Console.WriteLine(areEqual);
        Console.ReadKey();
    }
}

If you can't change your Enum, you can try this:

class Program
{
    public static bool Equal(DayOfWeek mine, System.DayOfWeek cSharp)
    {
        if (mine == DayOfWeek.Friday && cSharp == System.DayOfWeek.Friday       || 
            mine == DayOfWeek.Monday && cSharp == System.DayOfWeek.Monday       || 
            mine == DayOfWeek.Saturday && cSharp == System.DayOfWeek.Saturday   || 
            mine == DayOfWeek.Sunday && cSharp == System.DayOfWeek.Sunday       || 
            mine == DayOfWeek.Thursday && cSharp == System.DayOfWeek.Thursday   ||
            mine == DayOfWeek.Tuesday && cSharp == System.DayOfWeek.Tuesday     || 
            mine == DayOfWeek.Wednesday && cSharp == System.DayOfWeek.Wednesday)
            return true;

        return false;
    }

    static void Main(string[] args)
    {

        DateTime dateTime = DateTime.Now;
        DayOfWeek dayOfWeek = DayOfWeek.Tuesday;

        bool areEqual = Equal(dayOfWeek, dateTime.DayOfWeek);
        Console.WriteLine(areEqual);
        Console.ReadKey();
    }
}
Saeid Amini
  • 1,313
  • 5
  • 16
  • 26
  • I'm using my own DayOfWeek enum with flag for combine days of week in one variable. With using flag you need to set values as power of 2 – kenazs Jun 23 '19 at 08:17