Is current time within range

I know this question has been asked manytimes but mine has a small twist. There are many different shifts at work and I have two string shiftStart and shiftEnd. (example "6:00:00 PM" & "03:00:00 AM" respectively). This represents noon to morning. I am trying to make a function which tells me if DateTime.Now is within this timeperiod.

Note: the shift can be anything ... morning to noon, noon to morning, no fixed duration (like 8 hours).

static bool NowWithinShiftTime("6:00:00 PM", "03:00:00 AM")

Following is what I have tried but no matter what I do I cannot seem to find the logic... Please help me out...

static bool NowWithinShiftTime(string shiftStart, string shiftEnd)
    {
        DateTime startDate;
        DateTime endDate;
        DateTime now = DateTime.Now; 

        TimeSpan startTime = DateTime.Parse(shiftStart).TimeOfDay;
        TimeSpan endTime = DateTime.Parse(shiftEnd).TimeOfDay;

        if (startTime < endTime) // same day
        {
            startDate = new DateTime(now.Year, now.Month, now.Day) + startTime;
            endDate = new DateTime(now.Year, now.Month, now.Day) + endTime;
        }
        else // next day
        {
            startDate = new DateTime(now.Year, now.Month, now.AddDays(-1).Hour) + startTime;
            endDate = DateTime.Today.AddDays(1) + endTime;
        }
        if (now >= startDate && now <= endDate)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
Jon Skeet
people
quotationmark

Firstly, make all the business logic deal just with time-related types. (Personally I'd use my Noda Time library with its LocalTime type for this work, but...) The parsing can come in the calling code.

The logic is reasonably simple: if the "end time" is actually before the "start time" then just switch the two round and invert the result. After all, you're just dividing the day into "shift time" and "not shift time"... and a shift of (say) 8pm to 3am is "on" whenever a shift of 3am to 8pm is "off".

For example:

public bool NowWithinShiftTime(TimeSpan startTimeOfDay, TimeSpan endTimeOfDay)
{
    if (startTimeOfDay > endTimeOfDay)
    {
        return !NowWithinShiftTime(endTimeOfDay, startTimeOfDay);
    }
    TimeSpan now = DateTime.Now.TimeOfDay;
    return startTimeOfDay <= now && now < endTimeOfDay;
}

Notes:

  • I've made this deliberately half-closed, as that tends to be appropriate for intervals so that if you have abutting intervals, any given value falls into exactly one. Check exactly what you want, although it'll only be relevant for those two exact points in time per day.
  • The code is currently hard to test: I'd encourage you to abstract out the idea of "a clock" into an interface, so you can use a fake clock for testing. (Noda Time does this for you, and provides an appropriate FakeClock.)

people

See more on this question at Stackoverflow