enum with flags attribute - c#

I have the enum:
[Flags, Serializable,]
public enum WeekDays {
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
WeekendDays = Sunday | Saturday,
WorkDays = Monday | Tuesday | Wednesday | Thursday | Friday,
EveryDay = WeekendDays | WorkDays
}
And, I have property WeekDays in a class that contain value of WeekDays enum:
public int WeekDays {get; set;}
For example WorkDays contain 62( from Monday to Friday).
How to check that current WeekDays property contain current day?

Enum has method HasFlag to determine whether one or more bit fields are set in the current instance.

Use the bitwise operator & to see if a value is part of a set:
var today = WeekDays.Thursday;
var workdays = WeekDays.WorkDays;
if((today & workdays) == today) {
// today is a workday
}
if((today & WeekDays.Friday) == today) {
// it's friday
}

Use &:
[Flags, Serializable,]
public enum WeekDays
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
WeekendDays = Sunday | Saturday,
WorkDays = Monday | Tuesday | Wednesday | Thursday | Friday,
EveryDay = WeekendDays | WorkDays
}
public static WeekDays Days { get; set; }
private static void Main(string[] args)
{
WeekDays today = WeekDays.Sunday;
Days = WeekDays.WorkDays;
if ((Days & today) == today)
{
Console.WriteLine("Today is included in Days");
}
Console.ReadKey();
}

WeekDays weekDayValue = .... ;
var today = Enum.Parse(typeof(WeekDays),DateTime.Now.DayOfWeek.ToString())
bool matches = ( weekDayValue & today ) == today;

do:
int r = (int)(WeekDays.WorkDays & WeekDays.Sunday)
if (r !=0)
you have it.

You just need to use bitwise boolean logic to do this. if you were to say
WeekDays.Tuesday & WeekDays.WorkDays
then the boolean logic would return 4 (since 4&62 = 4).
Essentially the & is saying that for each bit position if both are 1 then return that number. So you then just need to check if it is > 0.
To get Today in your current format then you'll need to do a bit of maths...
(int)DateTime.Now.DayOfWeek will return the day of the week ranging from
0 (sunday) to 6 (saturday).
We need to map these to match your range. Fortunately this is easy to do with Math.Pow.
int today = Math.Pow(2,(int)DateTime.Now.DayOfWeek);
if (today&WeekDays.WorkDays>0)
isWorkDay = true;
else
isWorkDay = false;

Get all enum names and values, then perform 'and' calculation to test if WeekDays contains current day

Related

How to pass a DaysOfTheWeek enum value dynamically through code

I have the below enum value in task scheduler class, while I am creating a task I need to add days of the week depending on the checkbox selection. If the Monday checkbox is selected, I need to pass only Monday (or sometimes multiple days if other checkboxes are also selected).
In that below code how can I pass the multiple days dynamically?
public enum DaysOfTheWeek: short
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
AllDays = 127
}
DaysOfWeek = DaysOfTheWeek.Monday | DaysOfTheWeek.Sunday;
You can loop through your select list like this and create your enum value:
var days = new[] {1, 4, 32};
var daysOfTheWeek = DaysOfTheWeek.None;
foreach (var day in days)
{
daysOfTheWeek = daysOfTheWeek | (DaysOfTheWeek) day;
}
[Flags]
public enum DaysOfTheWeek
{
None = 0,
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
AllDays = 128
}
Decorate your enum with the Flags attribute:
[Flags]
public enum DaysOfTheWeek : short
Declare a DaysOfTheWeek variable and initialise it to zero:
DaysOfTheWeek days = 0;
Add flags to the enum value for each day which is ticked. Replace bool sunday = true, wednesday = true; here with your code which examines the checkboxes:
bool sunday = true, wednesday = true; // this is just proof of concept
if (sunday)
days |= DaysOfTheWeek.Sunday;
if (wednesday)
days |= DaysOfTheWeek.Wednesday;
days output:
Sunday, Wednesday
Your question doesn't mention loop, but your reply to my comment does. Do you mean something like:
DaysOfWeek = DaysOfTheWeek.Monday | DaysOfTheWeek.Sunday;
foreach (int day in Enum.GetValues(typeof(DaysOfTheWeek)))
{
if ( day & DaysOfWeek ) {
/* do something for this day */
}
}
As Shahriar Gholami suggested, here the complete code:
class Program
{
static void Main(string[] args)
{
var daysOfWeek = GetDaysOfTheWeek(new List<DaysOfTheWeek> {DaysOfTheWeek.Monday, DaysOfTheWeek.Sunday});
Console.WriteLine(daysOfWeek); //3
}
public static DaysOfTheWeek GetDaysOfTheWeek(List<DaysOfTheWeek> selectedDays)
{
var daysOfTheWeek = DaysOfTheWeek.None;
foreach (var day in selectedDays)
{
daysOfTheWeek = daysOfTheWeek | day;
}
return daysOfTheWeek;
}
}
[Flags]
public enum DaysOfTheWeek : short
{
None = 0,
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
AllDays = 127
}

How to get a date from year, month, week of month and Day of week ? C#

I have month, year, day of week and week of month, based on that I want to get a date. How can I do that? Following is my code but I am not getting correct result.
What am I missing here?
Code:
internal DateTime? GetDate(int year) // year = 2016
{
int month;
DateTime? date;
switch (Type)
{
case "CALCULATED":
month = FixedMonth; // month = 9
var firstDayOfWeek = new DateTime(year, month, 1); // firstDayOfWeek = 9/1/2016 12:00:00 AM
while (RestaurantSchedule.GetOneBasedDayOfWeek(firstDayOfWeek) <= DayOfWeek) // DayOfWeek = Monday
{
firstDayOfWeek = firstDayOfWeek.AddDays(1);
}
date = firstDayOfWeek.AddDays((WeekOfMonth - 1) * 7); // WeekOfMonth = 1, returns date = 9/1/2016 12:00:00 AM
if (date.Value.Month > month)
{
return date.Value.AddDays(-7);
}
return date;
default:
return new DateTime?();
}
}
public static OneBasedDayOfWeek GetOneBasedDayOfWeek(DateTime date) // date = 9/1/2016 12:00:00 AM
{
// returns Thursday
return (OneBasedDayOfWeek)Enum.Parse(typeof(OneBasedDayOfWeek), date.DayOfWeek.ToString());
}
// OneBasedDayOfWeek uses following enum
public enum DayOfWeek
{
None = 0,
Sunday = 1,
Monday = 2,
Tuesday = 3,
Wednesday = 4,
Thursday = 5,
Friday = 6,
Saturday = 7
}
Database entry:
HolidayDefinitionId Type FixedMonth FixedDay DayOfWeek WeekOfMonth Adjustment HolidayName Enabled
-------------------- ------------ ----------- ----------- ----------- ----------- ----------- --------------- -------
LABOR CALCULATED 9 0 2 1 0 Labor Day 1
PRESIDENTS CALCULATED 2 0 2 3 0 President's Day 1
Actual Results:
Presidents Day = 02/15/2016
Labor Day = 09/01/2016
Expected Results:
Presidents Day = 02/16/2016
Labor Day = 09/05/2016
Presidents day this year WAS on the 15th of February, so that was correct.
I got labour day to work like this:
For the first part I had to assume that you wanted to translate Microsofts DateTime (sunday = 0) to your Sunday = 1 enum.
public static DayOfWeek GetOneBasedDayOfWeek(DateTime date) // date = 9/1/2016 12:00:00 AM
{
// returns Thursday
return (DayOfWeek)((int)date.DayOfWeek + 1);
}
And in your main function, you want to iterate until you have actually reached your day of the week, not just while it's less (once you reach Sunday, your loop will always stop, since (int)Sunday < (int)AnyOtherDay
while (GetOneBasedDayOfWeek(firstDayOfWeek) != DayOfWeek)
I tested this with the dates a few years down the road and it seemed to work.

c# get non-working days in a month based on a shift

I have a List of days (working days) in an employee shift like below:
List<int> workingDays = new List<int>();
workingDays.Add(1); // monday
workingDays.Add(2); // tuesday
workingDays.Add(3); // wednesday
workingDays.Add(5); // friday
Those are the working days for an employee.
Now, I need to get all the days in a selected month where is a non-working day.
For example:
If July has 31 days I should get the following list:
July 3 // thursday is a non-working day
July 5 // saturday is a non-working day
July 6 // sunday is a nono-working day
July 10 // thursday is a non-working day
And so on...
Any clue on how to get that list?
UPDATE:
This is my attempt:
for (int day = 1; day <= DateTime.DaysInMonth(currentDate.Year, currentDate.Month); day++) {
DateTime dt = new DateTime(currentDate.Year, currentDate.Month, day);
var shiftDay = shifts.Where(s => (int) dt.DayOfWeek - 1 == s.Day && s.IsActive).First();
if (shiftDay == null) {
// this is a non-working day because wasn't found in the shift List
}
}
You should use DayOfWeek enumeration instead of int to make your code more readable and less prone to errors:
List<DayOfWeek> workingDays = new List<DayOfWeek>() {
DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Friday
};
var nonWorkingDays = Enumerable.Range(1, 31)
.Select(x => new DateTime(2014, 7, x))
.Where(d => !workingDays.Contains(d.DayOfWeek))
.ToList();

How can I define an enumeration where multiple values map to a single label?

Suppose, for the sake of this example, that I am trying to parse a file which specifies that two arbitrary bytes in the record represent the day of the week, thusly:
DayOfWeek:
- 0 = Monday
- 1 = Tuesday
- 2 = Wednesday
- 3 = Thursday
- 4 = Friday
- 5 = Saturday
- 6 = Sunday
- 7-15 = Reserved for Future Use
I can define an enumeration to map to this field, thusly:
public enum DaysOfWeek
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6
ReservedForFutureUse
}
But how can I define valid values for ReservedForFutureUse? Ideally, I'd like to do something like:
public enum DaysOfWeek
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6
ReservedForFutureUse = {7,8,9,10,11,12,13,14,15}
}
This problem is only exacerbated with more complicated fields; suppose, for example, that both 7 and 8, in this case, map to the same error case or something. How can one capture this requirement in a C# enumeration?
One funny quirk with enums is that a variable defined as a certain enum type can hold values that are not defined by any member of that enum:
public enum DaysOfWeek
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6
}
// in other code
DaysOfWeek someDay = (DaysOfWeek)42; // this is perfectly legal
This means that you don't really need to define all possible values that can appear, but can rather just specify those that mean something to your code. Then you can use some "catch-all" if- or switch-block to handle undefined values:
switch (someDay)
{
case DaysOfWeek.Monday:
{
// do monday stuff
break;
}
case DaysOfWeek.Tuesday:
{
// do tuesday stuff
break;
}
// [...] handle the other weekdays [...]
default:
{
// handle undefined values here
break;
}
}
Although a given underlying value may be mapped to multiple enum values, an enum value can have exactly one underlying value.
You could just do this
public enum DaysOfWeek
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6
Reserved1 = 7
...
Reserved8 = 15
}

select record with varios date/time criteria and periodicity(LINQ)

I have a several fields in my class: RecurrenceStart, RecurrenceEnd, Periodicity, RecurrenceType, WeekDays, DayNumber, WeekOfMonth.
For example, record in a DB with the following values:
Name = Event1
DateTimeStart = 2012-02-23 22:00:00.000
DateTimeEnd = 2012-12-31 23:30:00.000
Periodicity = 2
RecurrenceType = 1
WeekDays = 62
DayNumber = 1
WeekOfMonth = 1
It's mean that Event1 will go every 2 weeks on Monday, Tuesday, Wednesday, Thursday, and Friday from 22:00 to 23:30 and from 23 February to 31 December.
Another example:
Name = Event1
DateTimeStart = 2012-02-23 22:00:00.000
DateTimeEnd = 2012-12-31 23:30:00.000
Periodicity = 2
ReccurenceType = 2
WeekDays = 16
DayNumber = 25
WeekOfMonth = 0
It's mean that Event1 will go 25 day of every 2 months from 22:00 to 23:30 and from 23 February to 31 December.
This is enums:
[Flags, Serializable,]
public enum WeekDays {
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
WeekendDays = Sunday | Saturday,
WorkDays = Monday | Tuesday | Wednesday | Thursday | Friday,
EveryDay = WeekendDays | WorkDays
}
public enum WeekOfMonth {
None = 0,
First = 1,
Second = 2,
Third = 3,
Fourth = 4,
Last = 5
}
public enum RecurrenceType {
Daily = 0,
Weekly = 1,
Monthly = 2,
Yearly = 3,
Minutely = 4,
Hourly = 5,
}
This is my query:
Database.BaseEvents.Where(e =>
e.RecurrenceStart.Value.Date <= today &&
e.RecurrenceEnd.Value.Date >= today
).ToList();
This query check only start and end dates of event. How to build query that will be checks all another fields or checks another fields with helper method( but I need to perfomance).
Can you help me with this task?
PS. for first example my query will return Event1 every day from 2012-02-23 to 2012-12-31. But Event1 should return only is today 2012-02-23 - 2012-03-26. Then skip one weeks. Therefore, next dates when this event will return: from 2012-03-05 to 2012-11-05. then skip week again.... and so on.
Thanks and sorry for my english.

Categories