Algorithm to identify a shift and its type based on on and off times 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:


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 &gt; 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+" 07:00:00")); //OutTime of a night shift should be after or equal to 07AM on the next day

    if (shift.TotalHours &gt;= 11)
    {
        if ((compareInTimeTo8AM &lt; 0) &amp; (compareOutTimeTo7PM &gt;= 0))
        {
            return "Day Shift";
        }
        else if ((compareInTimeTo8PM &lt; 0) &amp; (compareOutTimeTo7AM &gt;= 0))
        {
            return "Night Shift";
        }
        else
        {
            return "Not a Shift";
        }
    }
    else
    {
        return "Not a Shift";
    }
}
First Things first:

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 &lt;= inTime(hour) &lt; 8AM AND 7PM &lt; outTime(hour))  
NightShift: if(7PM &lt;= inTime(hour) &lt; 8PM AND 7AM &lt; outTime(hour))  
InvalidShift: all else


Keep 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 &gt;= outTime)
    {
        throw new ArgumentException("inTime is not before outTime");
    }
    if ((outTime - inTime).Duration() &gt; 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 &gt;= DAY_SHIFT_START &amp;&amp; 
        inHour &lt; DAY_SHIFT_DEADLINE &amp;&amp; outHour &gt; NIGHT_SHIFT_START)
    {
        return Shift.DayShift;
    }
    else if (inHour &gt;= NIGHT_SHIFT_START &amp;&amp;
        inHour &lt; NIGHT_SHIFT_DEADLINE &amp;&amp; outHour &gt; DAY_SHIFT_START)
    {
        return Shift.NightShift;
    }
    else
    {
        return Shift.InvalidShift;
    }
}