patterncsharpMinor
Algorithm to identify a shift and its type based on on and off times
Viewed 0 times
shiftidentifytypealgorithmitsbasedandtimesoff
Problem
Following code is supposed to identify a shift and then it should identify whether the shift is a night or a day shift. The method will take 'in time' and 'out time' as two parameters.
These are the rules:
This code gives the intended result. Please let me know is the way I've done this acceptable? Do you have any better idea to achieve the same?
```
public string IdentifyShift(DateTime inTime, DateTime OutTime)
{
var compareInTimeToOutTIme = inTime.CompareTo(OutTime);
//Two random dates used to assign value '1 day' to timespan "aDay"
DateTime from= Convert.ToDateTime("05/01/2014 12:00:00");
DateTime to=Convert.ToDateTime("05/02/2014 12:00:00");
TimeSpan aDay = (to - from).Duration();
//If OutTime is less than the InTime that means the OutTime is on the next day
if (compareInTimeToOutTIme > 0)
{
OutTime = OutTime.Add(aDay);
}
TimeSpan shift = (OutTime - inTime).Duration();
var compareInTimeTo8AM =inTime.CompareTo(Convert.ToDateTime( inTime .ToShortDateString() +" 08:00:00")); //InTime of a day shift should be before 08AM
var compareOutTimeTo7PM = OutTime.CompareTo(Convert.ToDateTime(inTime .ToShortDateString ()+" 19:00:00")); //OutTime of a day shift should be after or equal to 07PM
var compareInTimeTo8PM =inTime.CompareTo(Convert.ToDateTime(inTime.ToShortDateString ()+" 20:00:00")); //InTime of a night shift should be before 08AM
string DayOfnightShiftOutTime= inTime.Add(aDay).ToShortDateString();
var compareOutTimeTo7AM =OutTime.CompareTo(Convert.ToDateTime(DayOfnightShiftOutTime+"
These are the rules:
- Day shift - From 7AM to 7PM
- Night shift - From 7PM to 7AM (on the next day)
- The employee should report before 8AM for a day shift, otherwise the shift will not be taken into account.
- The employee should report before 8PM for a night shift, otherwise the shift will not be taken into account.
- If an employee leaves before the regular off time of a shift, that shift will not be taken into account.
This code gives the intended result. Please let me know is the way I've done this acceptable? Do you have any better idea to achieve the same?
```
public string IdentifyShift(DateTime inTime, DateTime OutTime)
{
var compareInTimeToOutTIme = inTime.CompareTo(OutTime);
//Two random dates used to assign value '1 day' to timespan "aDay"
DateTime from= Convert.ToDateTime("05/01/2014 12:00:00");
DateTime to=Convert.ToDateTime("05/02/2014 12:00:00");
TimeSpan aDay = (to - from).Duration();
//If OutTime is less than the InTime that means the OutTime is on the next day
if (compareInTimeToOutTIme > 0)
{
OutTime = OutTime.Add(aDay);
}
TimeSpan shift = (OutTime - inTime).Duration();
var compareInTimeTo8AM =inTime.CompareTo(Convert.ToDateTime( inTime .ToShortDateString() +" 08:00:00")); //InTime of a day shift should be before 08AM
var compareOutTimeTo7PM = OutTime.CompareTo(Convert.ToDateTime(inTime .ToShortDateString ()+" 19:00:00")); //OutTime of a day shift should be after or equal to 07PM
var compareInTimeTo8PM =inTime.CompareTo(Convert.ToDateTime(inTime.ToShortDateString ()+" 20:00:00")); //InTime of a night shift should be before 08AM
string DayOfnightShiftOutTime= inTime.Add(aDay).ToShortDateString();
var compareOutTimeTo7AM =OutTime.CompareTo(Convert.ToDateTime(DayOfnightShiftOutTime+"
Solution
First Things first:
Method Signature:
C# conventions state, that public methods should be
TimeSpan, one Day:
Have you read up on the Constructors of TimeSpan? There is one, where you can do the following:
Returning Strings:
Returning strings is.. well It can be horrendous. In your case it's not a good idea: you have 3 Predefined States:
Given the case you introduce an enum like this:
Conditions in itself:
-
Day shift - From 7AM to 7PM
-
Night shift - From 7PM to 7AM (on the next day)
-
The employee should report before 8AM for a day shift, otherwise the shift will not be taken into account.
This gives following conditions, assuming inTime is before outTime (and they are not more than one Day apart):
Keep in mind, that as soon as the clock shows
Extracting Magic Numbers
You can further clarify the intentions of your Code, if you extract the magic numbers (7AM, 7PM, and so on) to named constants:
You can thus simplify your code to the following:
Method Signature:
public string IdentifyShift(DateTime inTime, DateTime OutTime)C# conventions state, that public methods should be
PascalCased (check), and local variables, as well as private fields, should be camelCased (partly). Furthermore your calculations are not depending on anything, but the method itself, they don't access class fields. You can, could and should make it static.public static string IdentifyShift(DateTime inTime, DateTime outTime)TimeSpan, one Day:
DateTime from= Convert.ToDateTime("05/01/2014 12:00:00");
DateTime to=Convert.ToDateTime("05/02/2014 12:00:00");
TimeSpan aDay = (to - from).Duration();Have you read up on the Constructors of TimeSpan? There is one, where you can do the following:
TimeSpan aDay = new TimeSpan(1,0,0,0);Returning Strings:
Returning strings is.. well It can be horrendous. In your case it's not a good idea: you have 3 Predefined States:
DayShift, NightShift, InvalidShift. These can be extracted to an enum structure. This would change your Method signature to the Following:public static Shift IdentifyShift(DateTime inTime, DateTime outTime)Given the case you introduce an enum like this:
enum Shift
{
DayShift, NightShift, InvalidShift
}Conditions in itself:
-
Day shift - From 7AM to 7PM
-
Night shift - From 7PM to 7AM (on the next day)
-
The employee should report before 8AM for a day shift, otherwise the shift will not be taken into account.
- The employee should report before 8PM for a night shift, otherwise the shift will not be taken into account.
- If an employee leaves before the regular off time of a shift, that shift will not be taken into account.
This gives following conditions, assuming inTime is before outTime (and they are not more than one Day apart):
DayShift: if(7AM <= inTime(hour) < 8AM AND 7PM < outTime(hour))
NightShift: if(7PM <= inTime(hour) < 8PM AND 7AM < outTime(hour))
InvalidShift: all elseKeep in mind, that as soon as the clock shows
08:00:00 / 20:00:00 respectively, that marks the shift as invalid.Extracting Magic Numbers
You can further clarify the intentions of your Code, if you extract the magic numbers (7AM, 7PM, and so on) to named constants:
const int DAY_SHIFT_START = 7;
const int DAY_SHIFT_DEADLINE = 8;
const int NIGHT_SHIFT_START = 19;
const int NIGHT_SHIFT_DEADLINE = 20;You can thus simplify your code to the following:
public static Shift IdentifyShift(DateTime inTime, DateTime outTime)
{
if (inTime >= outTime)
{
throw new ArgumentException("inTime is not before outTime");
}
if ((outTime - inTime).Duration() > new TimeSpan(1, 0, 0, 0))
{
throw new ArgumentException("outTime is more than 24 hours after inTime");
}
int inHour = inTime.Hour;
int outHour = outTime.Hour;
if (inHour >= DAY_SHIFT_START &&
inHour NIGHT_SHIFT_START)
{
return Shift.DayShift;
}
else if (inHour >= NIGHT_SHIFT_START &&
inHour DAY_SHIFT_START)
{
return Shift.NightShift;
}
else
{
return Shift.InvalidShift;
}
}Code Snippets
public string IdentifyShift(DateTime inTime, DateTime OutTime)public static string IdentifyShift(DateTime inTime, DateTime outTime)DateTime from= Convert.ToDateTime("05/01/2014 12:00:00");
DateTime to=Convert.ToDateTime("05/02/2014 12:00:00");
TimeSpan aDay = (to - from).Duration();TimeSpan aDay = new TimeSpan(1,0,0,0);public static Shift IdentifyShift(DateTime inTime, DateTime outTime)Context
StackExchange Code Review Q#49205, answer score: 4
Revisions (0)
No revisions yet.