algorithm for a schedule for the four-brigade system - excel

I need to program a shift schedule for three shift in a four-brigade system.
Each shift lasts eight hours.
First shift start at 6 am.
Second shift start at 2 pm.
Third shift start at 10 pm.
Each cycle has four days and 48 hours break.
The table below shows how is the schedule for January 20019.
"W" means a day off.
I would write a function which gets an argument date and number of shift and returns which brigade has a shift.
For example:
getBrigadeNumber('2019-01-27',1); // should return 'III' for schedule above
I completely don't have an idea how it writes.
I"ll write it in VBA, but I know php as well,
I will be grateful for any advice.

At first look the problem seems difficult - algorithm for three-shift schedule, but when you realize that the shifts are some patterns and these patterns doesn't change in time, than the problem starts to look very easy.
The idea to "Keeps first month in an array and when I will be need a specific day. I can count it for loops" will solve the problem. What I want to add is that it is not necessary to use loops. The shifts pattern repeats every 16 days – values for January 11th and January 27th are the same.
For a particular day d you can calculate the shift for each brigade considering the following pseudo-code:
D = The distance between a particular day d and January 1st in days.
A = Schedule for January 2019. A zero indexed array with 4 rows and 31 columns.
S1=A[1][D mod 16] will be the calculated shift number for brigade 1 at day d.
S2=A[2][D mod 16] will be the calculated shift number for brigade 2 at day d.
...
S4=A[4][D mod 16] will be the calculated shift number for brigade 4 at day d.
Knowing S1,S2,S3 and S4 is sufficient for getBrigadeNumber to return the correct value.

You can get this done without VBA, using the MATCH() worksheet function:
Imagine your month January is on row 1. You can use the MATCH() function to find the column where you have the 27th of January:
=MATCH(1;AB$2:AB$5;0)
Which stands for:
Find value 1, in column 'AB', inside the four rows (2 to 5), using exact matching.
Column 'AB' can be found as =OFFSET(A1;0;27).

Related

Excel hours worked calculation, based on specific time shifts

I have an excel with working hours in format Starting: 15:30 (A1) and finishing: 01:00 (B1). I would like to calculate the hours that i worked as nightshift (C1). The night shift is between 22:00 and 06:00. So if i work for example 17:00 to 02:15, i should get the number 04:15 as nightahift hours. I i work from 22:00 to 09.15 i should get 8 nightshift hours. I got the time difference with this
""=MOD(B2-A2;1)"" but this gets the whole shift and not the night ones only. Any suggestions?
It seems that this code works for one pair of columns, but i cannot figure out how to sum the results. The excel is seperated into columns, where every date has 2 columns for Starting and Ending shift
=MOD(D4-C4;1)24-(D4<C4)(22-6)-MEDIAN(D424;6;22)+MEDIAN(C424;6;22)
The ideal would be to have a formula to this result
=MOD(D4-C4;1)24-(D4<C4)(22-6)-MEDIAN(D424;6;22)+MEDIAN(C424;6;22)+
MOD(F4-E4;1)24-(F4<E4)(22-6)-MEDIAN(F424;6;22)+MEDIAN(E424;6;22)+
MOD(H4-G4;1)24-(H4<G4)(22-6)-MEDIAN(H424;6;22)+MEDIAN(G424;6;22) etc, but more compact way
Assuming that all input times are relative to 1/0/1900 (only time portion information). Therefore you need to consider when the date refers to the next day (adding 1). The condition for the end date is that if start > end, then the end date refers to the next day (+1). We take into account the above for the solution.
Assuming no excel version constraints as per the tags listed in the question, you can use the following formula in F2:
=LET(start, A2:A5, end, B2:B5, ns, D2, ne, D3+1, eEff, IF(end<start, end+1, end),
CALC, LAMBDA(isStart, MAP(start, eEff, LAMBDA(x,y, IF(y < ns, 0,
MEDIAN(IF(isStart, x, y), ns, ne))))), a, CALC(TRUE), b, CALC(FALSE),b-a)
I created a user LAMBDA function CALC just to avoid repetition of a similar calculation for the actual start (a) and end (b) of the working night interval. As you can see from the formula the night end (ne) has been adjusted to consider the next day. Similarly, we do the adjustment for the end time, calculating the effective end time (eEff) considering the next day when the end time (end) is lower than the start time (start).
We use MEDIAN to identify the actual interval in both cases. Here is the output:
where 0:00 means no time consumed during the night shift. The rest is just to use the correct format: hh:mm in the output to show durations during the night shift.
If you show the input data in numeric format, you can see the times referred to the first valid year in Excel (<= 1):
That is why we need to convert ne and end (in case it represents the next day), but it depends on whether or not you want to consider the next day in your input data. So for row 2 it represents 01:00 of the current day (0.04) so in the formula, we treat it as: 01:00 of the next day (1.04)

Is there any function in excel to find day time between two date and time in Excel?

I need a formula to calculate between two date and time excluding lunch time, holidays, weekend and between 09:00 and 18:00 work hours.
For example, 25/07/2022 12:00 and 29/07/2022 10:00 and answer has to be 1 day, 06:00
Thanks in advance.
I had a formula but it didn't work when hours bigger than 24 hours.
I don't know how you got to 1 day and 6 hours, but here is a customizable way to filter your time difference calculation:
=LET(
start,E3,
end,E4,
holidays,$B$3:$B$5,
array,SEQUENCE(INT(end)-INT(start)+1,24,INT(start),TIME(1,0,0)),
crit_1,array>=start,
crit_2,array<=end,
crit_3,WEEKDAY(array,2)<6,
crit_4,HOUR(array)>=9,
crit_5,HOUR(array)<=18,
crit_6,HOUR(array)<>13,
crit_7,ISERROR(MATCH(DATE(YEAR(array),MONTH(array),DAY(array)),holidays,0)),
result,SUM(crit_1*crit_2*crit_3*crit_4*crit_5*crit_6*crit_7),
result
)
Limitation
This solution only works on an hourly level, i.e. the start and end dates and times will only be considered on a full hour basis. When providing times like 12:45 as input, the 15 minute increment won't be accounted for.
Explanation
The 4th item in the LET() function SEQUENCE(INT(end)-INT(start)+1,24,INT(start),TIME(1,0,0)) creates an array that contains all hours within the start and end date of the range:
(transposed for illustrative purposes)
then, based on that array, the different 'crit_n' statements are the individual criteria you mentioned. For example, crit_1,array>=start means that only the dates and times after the start date and time will be counted, or crit_6,HOUR(array)<>13 is the lunch break (assuming the 13th hour is lunch time), ...
All of the individual crit_n's are then arrays of the same size containing TRUE and FALSE elements.
At the end of the LET() function, by multiplying all the individual crit_n arrays, the product returns a single array that will then only contain those hours where all individual criteria statements are TRUE:
So then the SUM() function is simply returning the total number of hours that fit all criteria.
Example
I assumed lunch hour to be hour 13, and I assumed the 28th to be a holiday within the given range. With those assumptions and the other criteria you already specified above, I'm getting the following result:
Which looks like this when going into the formula bar:
In cell G2, you can put the following formula:
=LET(from,A2:A4,to,B2:B4,holidays,C2:C2,startHr,E1,endHr,E2, lunchS, E3, lunchE, E4,
CALC, LAMBDA(date,isFrom, LET(noWkDay, NETWORKDAYS(date,date,holidays)=0,
IF(noWkDay, 0, LET(d, INT(date), start, d + startHr, end, d + endHr,
noOverlap, IF(isFrom, date > end, date < start), lunchDur, lunchE-lunchS,
ls, d + lunchS, le, d + lunchE,
isInner, IF(isFrom, date > start, date < end),
diff, IF(isFrom, end-date-1 - IF(date < ls, lunchDur, 0),
date-start-1 - IF(date > le, lunchDur, 0)),
IF(noOverlap, -1, IF(isInner, diff, 0)))))),
MAP(from,to,LAMBDA(ff,tt, LET(wkdays, NETWORKDAYS(ff,tt,holidays),
duration, wkdays + CALC(ff, TRUE) + CALC(tt, FALSE),
days, INT(duration), time, duration - TRUNC(duration),
TEXT(days, "d") &" days "& TEXT(time, "hh:mm") &" hrs "
)))
)
and here is the output:
Explanation
Used LET function for easy reading and composition. The main idea is first to calculate the number of working days excluding holidays from column value to to column value. We use for that NETWORKDAYS function. Once we have this value for each row, we need to adjust it considering the first day and last day of the interval, in case we cannot count as a full day and instead considering hours. For inner days (not start/end of the interval) it is counted as an entire day.
We use MAP function to do the calculation over all values of from and to names. For each corresponding value (ff, tt) we calculate the working days (wkdays). Once we have this value, we use the user LAMBDA function CALC to adjust it. The function has a second input argument isFrom to consider both scenarios, i.e. adjustment at the beginning of the interval (isFrom = TRUE) or to the end of the interval (isFrom=FALSE). The first input argument is the given date.
In case the input date of CALC is a non working day, we don't need to make any adjustment. We check it with the name noWkDay. If that is not the case, then we need we need to determine if there is no overlap (noOverlap):
IF(isFrom, date > end, date < start)
where start, end names correspond to the same date as date, but with different hours corresponding to start Hr and end Hr (E1:E2). For example for the first row, there is no overlap, because the end date doesn't have hour information, i.e. (12:00 AM), in such case the corresponding date should not be taken into account and CALC returns -1, i.e. one day needs to be subtracted.
In case we have overlap, then we need to consider the case the working hours are lower than the maximum working hours (from 9:00 to 18:00). It is identified with the name isInner. If that is the case, we calculate the actual hours. We need to subtract 1 because it is going to be one less full working day and instead to consider the corresponding hours (that should be less than 9hrs, which is the maximum workday duration). The calculation is carried under the name diff:
IF(isFrom, end-date-1 - IF(date < ls, lunchDur, 0),
date-start-1 - IF(date > le, lunchDur, 0))
If the actual start is before the start of the lunch time (ls), then we need to subtract lunch duration (lunchDur). Similarly if the actual end is is after lunch time, we need to discount it too.
Finally, we use CALC to calculate the interval duration:
wkdays + CALC(ff, TRUE) + CALC(tt, FALSE)
Once we have this information, it is just to put in the specified format indicating days and hours.
Now let's review some of the sample input data and results:
The interval starts on Monday 7/25 and ends on Friday 7/29, therefore we have 5 working days, but 7/26 is a holiday, so the maximum number of working days will be 4 days.
For the interval [7/25, 7/29] starts and ends on midnight (12:00 AM), therefore the last day of the interval should not be considered, so actual working days will be 3.
Interval [7/25 10:00, 7/29 17:00]. For the start of the interval we cannot count one day, instead 8hrs and for the end of the interval, the same situation 8hrs, so instead of 4days we are goin to have 2days plus 16hrs, but we need to subtract in both cases the lunch duration (1hr) so the final result will be 2 days 14hrs.

Excel formula to calculate elapsed minutes between 2 date timestamps only counting minutes during work hours

I have an excel sheet with about 50,000 records where I need to find the number of minutes between two date timestamps but I need to exclude any minutes that occurred during the times we are not working.
Our schedule is M-F 8:30am-5:30pm, Saturdays 8:30am-1:30pm
We don't work Sundays or holidays.
As an example
Cell B2: [7/3/2020 2:16:21 PM]
Cell C2: [7/6/2020 9:20:23 AM]
The manually calculated answer for this one should be about 244 minutes. Task started Friday afternoon, Saturday was a holiday, don't work Sundays, task completed at 9:20am on Monday.
Usually, I come here and start writing a question and by the time I've understood my own problem well enough to post a question I have figured it out on my own but not this time! Help!
Update:
#ForwardEd shared this...
=((I2-H2)
-MAX(0,(NETWORKDAYS.INTL(H2,I2,"0000011",$M$2:$M$12)-1+(WEEKDAY(I2,1)=7)))*TIME(15,0,0)
-MAX(0,(NETWORKDAYS.INTL(H2,I2,"1111101",$M$2:$M$12)-(WEEKDAY(I2,1)=7)))*TIME(19,0,0)
-NETWORKDAYS.INTL(H2,I2,"1111110",$M$2:$M$12)-(NETWORKDAYS.INTL(H2,I2,"0000000")
-NETWORKDAYS.INTL(H2,I2,"0000000",$M$2:$M$12)))*24*60
Where H:H is the Start Date Timestamp and I:I is the Response Date Timestamp and M2:M12 contains my holiday list.
It worked beautifully until I ran into an example like this:
H2 - 07/26/2020 7:48:45 PM
I2 - 07/27/2020 8:57:58 AM
The net result was -650.78333. It looks like anything that starts one one day and ends on the next is coming back as negative.
We want to measure the average response time in minutes for the applications that require manual underwriting. These start timestamps are times that loan applications were received online so they could come in any time of day. The stop times are timestamps that represent the system recorded response time. i.e. the timestamp where an underwriter first did something with the loan application. If a loan application was received at 7pm and was not auto-decisioned then a manual underwriter will need to do something with it the next day when we start working.
If that application came in at 7pm on Wed and is decisioned by an underwriter at 8:46am on Tuursday, we would want to document 16 minutes for that application - not 826 counting the hours between 7pm and 8:30am.
What you want to look at is NETWORKDAYS.INTL. Use this in conjunction with the custom settings to determine the number of Saturdays, Sundays and for the number of days in between your start and end time. You know you have X amount of time per day that is non working time, and Y amount per Saturday.
Then you formula in essence becomes
(End time - start time) - X * No. Weekdays - Y * No. Saturdays - No. Sundays - No. Holidays
Now there will be some tricks in there in order to count your days. but that is the gist of what it boils down to in a formula.
The formulas that are doing the brunt of the work are:
WORKDAY
NETWORKDAYS.INTL
TIME
I avoided the use of an if statement by using a boolean operation that excel will resolve from TRUE/FALSE to 1/0 when sent through a math operator. Side note: I read somewhere that this is also faster than an IF statement, but have no way of proving it and really does not matter on a small number of calculations.
WORKDAY
This formula will return the day of the week for a given date, and a set day of the week to be 1. It will be need in this solution to determine if the end date is a Saturday which has a value of 7 in default setup up as well when option 1 is picked. The format for the formula is:
WORKDAY(Excel Serial date, day 1 of the week)
For this solution
WEEKDAY(B3,1)
NETWORKDAYS.INTL
This formula will be used to count the number of specific days a start and an end date. It can exclude a custom weekend or count a custom week. If it is supplied with a list of dates that are holidays they can be excluded as well. The basic format of the formula is:
NETWORKDAYS.INTL(Start Date, End Date, Custom week choice or workweek pattern, range of holiday dates)
When entering the formula it will give you a list of predefined options for the weekend choices. It will not talk about the pattern.
The pattern is a string 7 digits long consisting of 1 or 0. 0's represents the days you want to count and 1's are days you want to ignore. An important part of the pattern is that the first entry is MONDAY. "1010111" would count only Tuesdays and Thursdays.
TIME
Excel stores date as an integer. 1 represents 1st of January 1900, 2 the 2nd of January 1900 and so on. Time is stored as a decimal or if you prefer the percentage/fraction of a day or 24 hour period. So rather than figuring out the math to determine what percentage of a day X number of hours is, it is simpler to let excel calculate it for us and make the number a little more understandable to someone who may be deciphering the formula later. The basic format of the formula is:
TIME(Hours, Minutes, Seconds)
So as stated earlier, 6 key components need to be determined:
X - Amount of non working time after a weekday
Y - Amount of non working time after a Saturday
Number of weekdays
Number of Saturdays
Number of Sundays
Number of holidays
1) Determine Weekday Non-Working Hours
Based on the supplied information that work day stops at 1730 and starts as 0830. There are a couple of ways of doing the math. Subtract the working hours from 24 hours or count the non work hours at the end of the day and add them to the non work hours at the start of the day.
24 - (17.5 - 8.5) = 15
or
(24 - 17.5) + (8.5 - 0) = 15
For this example 15 will be hard coded into the final formula
2) Determine Saturday Non-Working Hours
Similar to above. Note that we are ignoring Sunday as it is a designated non working day which we already know is 24 hours or 1 day. We are just interested in the time between end of shift Saturday and start of the next normal working Monday. So it really gets calculated the same with just with difference end of shift time.
24 - (13.5 - 8.5) = 19
or
(24- 13.5) - (8.5 - 0) = 19
For this example 19 will be hard coded into the final formula
3) Determine Number of Weekdays
Based on the description earlier of of NETWORKDAYS.INT and working with the assumption that holidays are stored in the range F2:F2, and using a pattern of "0000011" the number of weekdays the formula will be as follows:
=NETWORKDAYS.INTL(B2,B3,"0000011",F2)
For this example the formula is place in cell F6
4) Determine Number of Saturdays
Similar 3) adjust the pattern to only select Saturdays by using "1111101"
=NETWORKDAYS.INTL(B2,B3,"1111101",F2)
For this example the formula is place in cell F7
5) Determine Number of Sundays
Similar 4) adjust the pattern to only select Saturdays by using "1111110"
=NETWORKDAYS.INTL(B2,B3,"1111110",F2)
For this example the formula is place in cell F8
6) Determine Number of Holidays
To get the number of holidays there is not a direct way of doing it. Instead take the difference between all days counted without holidays being factored in and all days counted with holidays counted in.
=NETWORKDAYS.INTL(B2,B3,"0000000")-NETWORKDAYS.INTL(B2,B3,"0000000",$F$2:F2)
For this example the formula is place in cell F9
Now at this point I would love to say just substitute all of the above into the generic formula, but there are a couple of special cases that need to be taken care of. You may have also noted I have not used the WEEKDAY formula yet.
So in order to count the number of days to which X is going to apply, its really the number of days minus 1. The minus 1 is because you want to cont the intervals between days, not the number of days themselves. This gets a little bit more trickier when the end day is a Saturday because there is still an interval there but Saturday is not counted as a weekday. So the True count for number of weekday intervals is:
=MAX(0,(F6-1+(WEEKDAY(B3,1)=7)))
I originally had the MAX(0, calc) in there to prevent the posibility of the day count being negative. After arriving at this final format it may not be needed and you might get away with the following but its untested:
=F6-1+(WEEKDAY(B3,1)=7)
This same concept needs to be applied to your Saturday count. If you job ends on Saturday you do not need to subtract the non working hours after the last Saturday. You formula will look like:
=MAX(0,(F7-(WEEKDAY(B3,1)=7)))
and again further testing is required to make sure MAX can be removed, but if it can then the formula would look like:
=F7-(WEEKDAY(B3,1)=7)
So now with the understanding how dates and times are stored, determine the time difference between start end end time and subtract all the non working hours.
=(B3-B2)-MAX(0,(F6-1+(WEEKDAY(B3,1)=7)))*TIME(15,0,0)-MAX(0,(F7-(WEEKDAY(B3,1)=7)))*TIME(19,0,0)-F8-F9
Now you will not want to use helper cells, so you can take each of the individual formula from F6 to F9 and wind up with:
=(B3-B2)-MAX(0,(NETWORKDAYS.INTL(B2,B3,"0000011",F2)-1+(WEEKDAY(B3,1)=7)))*TIME(15,0,0)-MAX(0,(NETWORKDAYS.INTL(B2,B3,"1111101",F2)-(WEEKDAY(B3,1)=7)))*TIME(19,0,0)-NETWORKDAYS.INTL(B2,B3,"1111110",F2)-(NETWORKDAYS.INTL(B2,B3,"0000000")-NETWORKDAYS.INTL(B2,B3,"0000000",$F$2:F2))
The formula looks unruly, but is easier to understand when broken down into its parts.
Now the last step is to get the answer to display in minutes. There are two choices.
You can leave it as it is in an excel serial date format and change the formatting of to a custom format of [m]. The [ ] will force it into minutes and prevent spill over to hours. It will also round to the nearest minute.
You can convert the results to minutes by multiplying by 24*60 and the value will be in minutes and decimal of minutes.
Note that:
A11 has Time formatting applied
A12 has General formatting applied
A14 has custom formatting of [m] applied
It should be something like this:
Create a calendar table with the workinghours for each days in the year you have data in
Date | StartTime | End time
1/1/2020 1/1/2020 8:30:00 PM 1/1/2020 5:30:00 PM
...
7/3/2020 7/3/2020 8:30:00 PM 7/6/2020 5:30:00 PM
...
12/31/2020
Then paste this code in a module
Function CalcDays(dStart As Date, dEnd As Date, daysCalendar As Range)
Dim Cell As Range
Dim MinDaysCalendar As Date, MaxDaysCalendar As Date
Dim aWSF As WorksheetFunction
Set aWSF = Application.WorksheetFunction
'check the minimum en the maximum date in the calendar
With aWSF
MinDaysCalendar = .Min(daysCalendar)
MaxDaysCalendar = .Max(daysCalendar)
End With
'if the date you check is not in the calendar, exit the function
If dStart < MinDaysCalendar Or dStart > MaxDaysCalendar Then
MsgBox "Date not in calendar"
Exit Function
End If
If dEnd < MinDaysCalendar Or dEnd > MaxDaysCalendar Then
MsgBox "date not in calendar"
Exit Function
End If
'sum the time of all the dates between the start and the end
'pick min and max in order to start and stop at the right time per day
Dim tempTime As Integer
With daysCalendar
For i = 1 To .Rows.Count
If .Cells(i, 2).Value >= CLng(dStart) And .Cells(i, 3).Value <= CLng(dEnd) Then
daytime = aWSF.Max(.Cells(i, 2).Value, dStart) - aWSF.Min(.Cells(i, 3).Value, dEnd)
End If
tempTime = tempTime + daytime
Next i
End With
'return the total time
CalcDays = tempTime
End Function
You can call the function by typing =calcdays in a cell and then give the startDay, endDay and calendar column as parameters.
There might still be some flaws in this code but I think we can manage those.

How can i develop a working shift formula that can have four posibilities of output

I've been trying to develop a formula in excel to calculate the working shift by date and time, however I've got some troubles trying to reach a efficient one, some of them are the next ones:
-The validity of the formula in time is short.
-It has to be completely condicionated to wrok fine, demands a lot of computing, and it still has the validity short.
Now the bullets to define a formula are the next ones:
-The output must any of "1", "2", "3" and "4" with its conditions, the conditions are the next ones:
*1 is the shift where you work since 6:10 am to 6:10 pm, from sunday to tuesday and the wednesday you work one week and the other you dont. (For this year, the week number of the year must be pair for you to work in shift 1 the wednesday, the unpair one you dont)
*2 is the shift where you work since 6:10 am to 6:10 pm, from thursday to saturday and the wednesyou alternate the day with shift 1, example shift 1 worked one week the wednesday then you work the next one the wednesday.
*3 is the shift where you work since 6:10 pm to 6:10 am, from sunday to tuesday and the wednesday you work one week and the other you dont.
*4 is the shift where you work since 6:10 pm to 6:10 am, from thursday to saturday and the wednesyou alternate the day with shift 3, example shift 3 worked one week the wednesday then you work the next one the wednesday.
I've tried conditioning and it works but it has the two points I explain in the question. conditioning you get it to work like 3 years.
I'm looking for a synthesized way to calculate it with its two variables (Date and time) in a way really complete and maybe analyze the way to do it.
The formula is the next one (in cell F14 I've date and time, it can be separated there's no problem with that) :
=IF(AND(WEEKDAY(F14)<=3,VALUE(RIGHT(ROUND(F14,5),6))>6.16666666/24,VALUE(RIGHT(ROUND(F14,5),6))<18.16666666/24),"T1",IF(AND(WEEKDAY(F14)>=5,VALUE(RIGHT(ROUND(F14,5),6))>6.16666666/24,VALUE(RIGHT(ROUND(F14,5),6))<18.16666666/24),"T2",IF(AND(WEEKDAY(F14)=4,VALUE(RIGHT(ROUND(F14,5),6))>6.16666666/24,VALUE(RIGHT(ROUND(F14,5),6))<18.16666666/24,VALUE(RIGHT(YEAR(F14)/2,2))=0.5,VALUE(RIGHT(ROUND(WEEKNUM(F14)/2,2),2))<>0.5),"T1",IF(AND(WEEKDAY(F14)=4,VALUE(RIGHT(ROUND(F14,5),6))>6.16666666/24,VALUE(RIGHT(ROUND(F14,5),6))<18.16666666/24,VALUE(RIGHT(ROUND(WEEKNUM(F14)/2,2),2))=0.5),"T2",IF(AND(WEEKDAY(F14)=1,VALUE(RIGHT(ROUND(F14,5),6))<6.16666666/24),"T4",IF(AND(WEEKDAY(F14)<=4,VALUE(RIGHT(ROUND(F14,5),6))<6.16666666/24),"T3","N"))))))
So, I have to be a little honest. I had every intent to walk through your formula, figure out why we got different results, and explain what happened. But I couldn't stay focused and my mind started drifting towards more pleasant things like responding to HOA letters, paying taxes, and solving Pi. So I didn't do it.... Moving on!
I believe I understood what you needed. There are four shifts in total, with two shifts per day. Shifts 1 and 3 work Sunday through Tuesday, 1 starts at 06:10 and is relieved at 18:10 when shift 3 starts. It is similar for Shifts 2 and 4, their days are Thursday through Saturday and they have the same hours. Wednesdays alternate between the two groups with 1 and 3 taking Wednesday when the week number is wholly divisible by two. Shifts 2 and 4 take the alternate Wednesday.
You can see my test data in the image below and I believe you'll find the results align with my explanation. You'll note there is a data column to the left of the date and another to the right. This is because I tested two different methods. The results align so I have high confidence in the quality of my work and I remain hopeful that put you in the right direction.
The column to the left of the dates uses a very short formula:
=CoveringShift(B1)
And the column to the right of the dates uses a much longer formula:
=IF(WEEKDAY(B1)<>4,IF(WEEKDAY(B1)<=3,IF(AND(TIME(HOUR(B1),MINUTE(B1),0)>=TIME(6,10,0),TIME(HOUR(B1),MINUTE(B1),0)<TIME(18,10,0)),1,3),IF(AND(TIME(HOUR(B1),MINUTE(B1),0)>=TIME(6,10,0),TIME(HOUR(B1),MINUTE(B1),0)<TIME(18,10,0)),2,4)),IF(ISEVEN(WEEKNUM(B1)),IF(AND(TIME(HOUR(B1),MINUTE(B1),0)>=TIME(6,10,0),TIME(HOUR(B1),MINUTE(B1),0)<TIME(18,10,0)),1,3),IF(AND(TIME(HOUR(B1),MINUTE(B1),0)>=TIME(6,10,0),TIME(HOUR(B1),MINUTE(B1),0)<TIME(18,10,0)),2,4)))
Ok, ok, you caught me. I used VBA to create a User Define Function. This is the code:
Option Explicit
Public Function CoveringShift(TimeQuery As Date) As Single
Dim AM As Date
Dim PM As Date
Dim Shifts As String
Dim iVal As Integer
AM = TimeSerial(6, 10, 0)
PM = TimeSerial(18, 10, 0)
iVal = Application.WorksheetFunction.WeekNum(TimeQuery)
Select Case Weekday(TimeQuery, vbSunday)
Case 1 To 3
Shifts = "1,3"
Case 5 To 7
Shifts = "2,4"
Case 4
If iVal / 2 - Int(iVal / 2) = 0 Then
Shifts = "1,3"
Else
Shifts = "2,4"
End If
Case Else
MsgBox "Something bad happened"
End Select
Select Case TimeValue(TimeQuery)
Case Is < AM
Shifts = Right(Shifts, 1)
Case AM To DateAdd("s", -1, PM)
Shifts = Left(Shifts, 1)
Case Is >= PM
Shifts = Right(Shifts, 1)
Case Else
MsgBox "Something bad happened"
End Select
CoveringShift = CSng(Shifts)
End Function
Personally, I prefer the cleanliness and readability of the UDF; but sometimes VBA's baggage isn't worth carrying.
I hope this helped in some way!

Determine if date is a workday in Excel

I have a date in column H10 and need to add 45 days to this date in the next Column I
If there are not dates Column I must be blank
If the 45th day falls on a weekend the calculation must move to the next workday which is Monday
You need to combine two fundamental functions.
First, DATE + INT = DATE. For example, if H10 = 1/8/2015 and H11 = H10 + 10 then H11 will show 1/18/2015.
In your case, you want to use H10 + 45.
Second, you can use the Weekday(date,mode) function to determine the day of the week. Personally, for your purpose, you could use weekday(h10 + 45, 2) which would give a 1-5 for MTWRF, and a 6-7 for a weekend day. So something like
=if(weekday(h10+45,2) < 6, "weekday", "weekend")
=if(weekday(h10+45,2) = 1, "Monday!!", "not monday...")
But we aren't done yet - you need to make sure your day actually ends up on a weekday. So we can do something like this - when determining a weekday, we can use that to determine how much we need to add. If we end up with a 6 (Saturday) we want to add 2 days to push it to a Monday. In the case of a 7, we want to add 1 day to push it to a Monday. Thus, we can simply take the 8 - weekday(h10+45) to add when it's a weekday. So our add value becomes
// determine day type weekday weekend, so add the offset
= if(weekday(h10+45) < 5, h10+45, h10 + 45 + (8 - weekday(h10+45))
You also have a requirement about being blank, so you'll want to wrap whatever you use with
=if(isblank(h10),"", /* your real function here */)
You can combine the functions for IF(), WEEKDAY() and WORKDAY() to calculate your finish date and ensure that it does not fall on a weekend.
I've used
WEEKDAY(WORKDAY(H10+45),16)
to have Saturday and Sunday be represented as days 1&2 respectively.
IF(WEEKDAY(WORKDAY(H10,45),16)=1,WORKDAY(H10,45)+2,IF(WEEKDAY(WORKDAY(H10,45),16)=2,WORKDAY(H10,46),H10))

Resources