1

I am doing a calender page to display day, night and off days of shift work.

The schedule goes like this: 7 days off, 4 nights, 3 days off, 1 day off, 3 nights, 3 days off, 4 days and then the 28 day cycle starts all over again. The cycle always starts on Friday.

There are 4 different crews: each one starts a week after the other.

So I have a sql table that just has the month, day and year of the first 28 day cycle of the first crew's 7 off and I suck that into a collection and add the fields to calculate the other crews' starting 7 off.

The calender has a different color to show whether its your day off, nights, days. So I go through the list and use the first day of the cycle as an index into an array of:

static int[] DaysArray = new int[28] {0,0,0,0,0,0,0,2,2,2,2,0,0,0,1,1,1,0,2,2,2,0,0,0,1,1,1,1}; // 0 - day off, 1 - days, 2 - nights

All I'm interested in is determining at what point into the 28 day cycle the start of the month is and I just color in the rest of the days with the appropriate color. Here's the routine I'm struggling with:

protected int GetDayNightOff(int day)
{
    day--;
    day -= 28;
    day = Math.Abs(day);
    day--;
    return DaysArray[day];
}

If the first day of the cycle falls on the 1st, then I want to show the starting color using index 0; the 2nd: index 27; 3rd: index 26 and so on. I know there's a simple solution but I just can't seem to get my head around it.

Hope someone could help, it would be greatly appreciated.

David Pilkington
  • 13,528
  • 3
  • 41
  • 73
Dan H
  • 15
  • 5
  • 1
    you array doesn't match what the description for the schedule you gave – Jonesopolis Nov 05 '13 at 15:03
  • Your `GetDayNightOff(int day)` function only accepts a day of the month as an argument, but shouldn't your algorithm require the date that the cycle first began? – Kyle G. Nov 05 '13 at 15:08
  • 1
    I would very strongly recommend using built-in date types for this. Date logic is always unexpectedly more tricky than you think and the built-in types usually handle things in a nice, easy to use way. – confusopoly Nov 05 '13 at 15:10

1 Answers1

3

I recommend that you use DateTime and an enum instead of magic ints. The code will be easier to read, and since dates are actually pretty hard to get right, it's good to use a library instead of doing it yourself. Then you can subtract your target day from the cycle start day and get the Days property of that TimeSpan.

static Working[] DaysArray = { Working.Off, Working.Off, Working.Off, Working.Off, Working.Off, Working.Off, Working.Off, Working.Nights, Working.Nights, Working.Nights, Working.Nights, Working.Off, Working.Off, Working.Off, Working.Days, Working.Days, Working.Days, Working.Off, Working.Nights, Working.Nights, Working.Nights, Working.Off, Working.Off, Working.Off, Working.Days, Working.Days, Working.Days, Working.Days };
public enum Working
{
    Off,
    Days,
    Nights,
}
public Working GetDayNightOff(DateTime cycleStart, DateTime day)
{
    var days = (day - cycleStart).Days;
    days %= DaysArray.Length;
    if (days < 0)
        days += DaysArray.Length;
    return DaysArray[days];
}

The calculations on days allow day to be far from cycleStart.

Community
  • 1
  • 1
Tim S.
  • 55,448
  • 7
  • 96
  • 122